[转] python关于ctypes使用char指针与bytes相互转换的问题
最近研究人脸识别,需要用python调用so动态库,涉及到c/c++中的指针字符串转Python的bytes对象的问题。
按照ctypes的文档,直观方式是先创建对应的类型数组,再将指针取地址一一赋值:
from ctypes import * |
from ctypes import * p=(c_char * 10)() for i in range(10): p[i] = i b=bytes(bytearray(p)) print(b)
搜寻了各种资料,都未能找到更好的。。。直到ctypes.string_at
_string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) |
_string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) def string_at(ptr, size=-1): """string_at(addr[, size]) -> string Return the string at addr.""" return _string_at(ptr, size)
于是char*转bytes可以直接用string_at方法,传入指针地址,以及字符串长度即可。
同样的问题,bytes对象需要传给c/c++代码。。。
直观方式同样是创建char数组array,拷贝bytes之后,再用cast强制转换成c_char_p
from ctypes import * |
from ctypes import * p=(c_char * 10)() for i in range(10): p[i] = i m=cast(p, c_char_p) print(m)
比较奇葩的是cast得到的对象,如果我们直接用bytes对象cast。。。
from ctypes import * |
from ctypes import * b=b'0123456789' m=cast(p, c_char_p) print(m)
吼吼,奇迹出现了,bytes对象cast成了char*指针。。。用string_at转换看看
string_at(m) |
string_at(m)
总结一下:
1、bytes基于Buffer Protocol,查看其c实现https://hg.python.org/cpython/file/3.4/Objects/bytesobject.c
2、string_as的c代码https://hg.python.org/cpython/file/3717b1481d1b/Modules/_ctypes/_ctypes.c
static PyObject * |
static PyObject * string_at(const char *ptr, int size) { if (size == -1) return PyString_FromString(ptr); return PyString_FromStringAndSize(ptr, size); }
3、cast的c代码同样在_ctypes.c(https://hg.python.org/cpython/file/3717b1481d1b/Modules/_ctypes/_ctypes.c)
static PyObject * |
static PyObject * cast(void *ptr, PyObject *src, PyObject *ctype) { CDataObject *result; if (0 == cast_check_pointertype(ctype)) return NULL; result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL); if (result == NULL) return NULL; /* The casted objects '_objects' member: It must certainly contain the source objects one. It must contain the source object itself. */ if (CDataObject_Check(src)) { CDataObject *obj = (CDataObject *)src; /* CData_GetContainer will initialize src.b_objects, we need this so it can be shared */ CData_GetContainer(obj); /* But we need a dictionary! */ if (obj->b_objects == Py_None) { Py_DECREF(Py_None); obj->b_objects = PyDict_New(); if (obj->b_objects == NULL) goto failed; } Py_XINCREF(obj->b_objects); result->b_objects = obj->b_objects; if (result->b_objects && PyDict_Check(result->b_objects)) { PyObject *index; int rc; index = PyLong_FromVoidPtr((void *)src); if (index == NULL) goto failed; rc = PyDict_SetItem(result->b_objects, index, src); Py_DECREF(index); if (rc == -1) goto failed; } } /* Should we assert that result is a pointer type? */ memcpy(result->b_ptr, &ptr, sizeof(void *)); return (PyObject *)result; failed: Py_DECREF(result); return NULL; }
[转] python关于ctypes使用char指针与bytes相互转换的问题的更多相关文章
- 初始化char指针--赋值和strcpy() 本质区别【转】
原文地址:http://hi.baidu.com/todaygoodhj/item/0500b341bf2832e3bdf45180 使用常量字符串初始化char指针,或者使用strcpy复制,从语法 ...
- char[]数组与char *指针的区别
char[]数组与char *指针的区别 问题描述 虽然很久之前有看过关于char指针和char数组的区别,但是当时没有系统的整理,到现在频繁遇到,在string,char[], char *中迷失了 ...
- char指针
1.在C语言中,没有字符串类型,因此使用char指针表示字符串. 2.那么问题来了,使用char* 表示字符串,到哪里是结尾呢?因此需要一个特殊的字符作为哨兵,类似迭代器中的end(),这个哨兵就是' ...
- char数组与char指针
1.以字符串形式出现的,编译器会在结尾自动添加\0,思考,为什么? 存在的C语言方法,如strlen(s),计算字符串的长度,其中s指针.strlen要计算字符串长度,必须知道哪里是结尾,因此使用\0 ...
- C: 当字符数组首指针转化成char *指针,sizeof(*ptr)不为array的size
#include <stdio.h> #include <string.h> int main() { char a[10] = "\0"; char *p ...
- char 指针如何判断字符串需要输出长度
先上代码: #include <stdio.h> #include <string.h> ] = "; int func1(const char *ip) { pri ...
- C++中将对象this转换成unsigned char指针
示例程序 // ---CodeBlob.h--- #ifndef CODEBLOB_H_ #define CODEBLOB_H_ class CodeBlob { private: const cha ...
- Java之byte、char和String类型相互转换
package basictype; /** * byte.char和String类型相互转换 */ public class CHJavaType { public static void main ...
- python pip 'nonetype' object has no attribute 'bytes'
python pip 'nonetype' object has no attribute 'bytes' 更新 pip for Windows : python -m pip install -U ...
随机推荐
- 模板 - Floyd
void Floyd(){ for(int k = 1; k <= n; ++k) { for(int i = 1; i <= n; ++i) { for(int j = 1; j < ...
- GitHub入门使用
1.首先注册账号. 2.新建仓库. 3.安装GitBash 4.首先要在本地创建一个ssh key. $ ssh -keygen -t rsa -C "your email@.com&quo ...
- vue-cli proxyTable中跨域中pathRewrite 解释
问:proxyTable 里面的pathRewrite里面的‘^/iclient’:'' 什么意思? 答:用代理, 首先你得有一个标识, 告诉他你这个连接要用代理. 不然的话, 可能你的 html ...
- Linux系统性能测试工具(四)——CPU性能测试工具之super_pi、sysbench
本文介绍关于Linux系统(适用于centos/ubuntu等)的CPU性能测试工具-sysbench.CPU性能测试工具包括: super_pi: sysbench——不仅可以测试CPU性能,而且可 ...
- python并发编程中的多进程(代码实现)
一.multipricessing模块的介绍 python中的多线程无法利用多核优势,如果想要充分的使用多核CPU资源,在python中大部分情况下需要用多线程,python提供了multiproce ...
- dockerfile制作笔记
dockerfile语法格式: FROM: 基础镜像(就是在什么镜像上面做) MAINTAINER: 镜像创建者信息(作者的信息) EXPOSE: 开放的端口 ENV: 设置变量 ...
- 合肥学院ACM集训队第一届暑假友谊赛 B FYZ的求婚之旅 D 计算机科学家 F 智慧码 题解
比赛网址:https://ac.nowcoder.com/acm/contest/994#question B FYZ的求婚之旅 思路: 然后用快速幂即可. 细节见代码: #include <i ...
- adam优化
AdaGrad (Adaptive Gradient,自适应梯度) 对每个不同的参数调整不同的学习率, 对频繁变化的参数以更小的步长进行更新,而稀疏的参数以更大的步长进行更新. gt表示第t时间步的梯 ...
- java 中的编码(二)
UTF-16编码规则: 按照UTF-16编码规则计算下Unicode码位为 U+10002 (十进制:65538)的字符的UTF-16编码表示. U+10002落在 [U+10000, U+10FFF ...
- C++ GUI Qt4学习笔记03
C++ GUI Qt4学习笔记03 qtc++spreadsheet文档工具resources 本章介绍创建Spreadsheet应用程序的主窗口 1.子类化QMainWindow 通过子类化QM ...