[转] 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 ...
随机推荐
- 断开ssh链接在后台继续运行命令
转载:http://blog.csdn.net/v1v1wang/article/details/6855552 对于linux运维,我们都是使用ssh登录到服务器,如果我们运行的任务需要很长时间或不 ...
- shopnc如何配置微信支付和支付宝支付
步骤一,支付宝账号申请 申请支付宝商家账号 ,填写好公司名称,资质,审核过了,然后填写下面这些参数 步骤二 微信支付申请 登陆微信公众平台-企业微信支付,得到商户号,再申请密钥 注意:支付宝加密方式 ...
- Maven clean install 跳过单元测试
1.使用MVN命令 mvn clean install -DskipTests 或者 mvn clean install -Dmaven.test.skip=true 2.Eclipse中设置clea ...
- POI读取文件的最佳实践
POI是 Apache 旗下一款读写微软家文档声名显赫的类库.应该很多人在做报表的导出,或者创建 word 文档以及读取之类的都是用过 POI.POI 也的确对于这些操作带来很大的便利性.我最近做的一 ...
- Python爬虫之urllib.parse详解
Python爬虫之urllib.parse 转载地址 Python 中的 urllib.parse 模块提供了很多解析和组建 URL 的函数. 解析url 解析url( urlparse() ) ur ...
- 43. Multiply Strings (JAVA)
Given two non-negative integers num1 and num2represented as strings, return the product of num1 and ...
- #include <xxx.h>和#include "xxx.h"的区别
<>代表在系统目录下查找该头文件(系统定义头文件) ""代表在用户目录下查找该头文件(自定义头文件)
- Django视图中使用本地缓存
Django服务器视图使用缓存可以大大减小服务器的压力,对数据实时性要求不高的场景使用缓存非常适合. 使用Django本地缓存 1. 在settings.py配置CACHES CACHES = { ' ...
- Selenium 2 & WebDriver &多线程 并发
我用的是Selenium2,至于它的背景和历史就不赘述了.Selenium2也叫WebDriver.下面讲个例子,用WebDriver+java来写个自动化测试的程序.(如果能用firefox去测试的 ...
- bzoj3754 Tree之最小方差树 最小生成树+推性质
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3754 题解 感觉这个思路挺神仙的. 后悔没有好好观察题目的数据范围,一直把 \(n\) 和 \ ...