将char*数组从c dll传递到python

将char*数组从c dll传递到python,python,c,dll,ctypes,Python,C,Dll,Ctypes,我有一个简单的dll,它的函数以回调函数为参数,有时调用它并传递无符号 字符*数组。我想在python中使用它 以下是dll源代码: typedef void (*buffer_ready_callback_t)(unsigned char* data, int len); extern "C" void __declspec(dllexport) example(buffer_ready_callback_t cb) { unsigned char* data

我有一个简单的dll,它的函数以回调函数为参数,有时调用它并传递无符号 字符*数组。我想在python中使用它

以下是dll源代码:

typedef void (*buffer_ready_callback_t)(unsigned char* data, int len);

extern "C" void __declspec(dllexport) example(buffer_ready_callback_t cb) {
     unsigned char* data = (unsigned char*)malloc(100);
     memset(data,0xAA,100);
     
     cb(data,100);

     free(data);
}
在python中,我是这样使用它的:

library = cdll.LoadLibrary("example.dll")
buffer_ready_callback_t = CFUNCTYPE(None, c_char_p, c_int, c_ulong)

def api_callback_buffer(self, data, ln, ts):    
        #problem here
        pass

function = self.library.example
function.restype = None
function.argtypes = [buffer_ready_callback_t]
api_buffer_cb = buffer_ready_callback_t(api_callback_buffer)        
function(api_buffer_cb);
所以问题是如何使用回调函数中接收到的数据? 是否可以转换为bytearray、list或numpy数组或其他可以在python中使用的格式

感谢您的光临

这个问题有点不清楚。给定现有代码,您应该已经在回调函数中将数据作为字节

这里有一个例子

dll00.c:

#包括
#包括
#如果已定义(_WIN32)
#定义DLL00_导出_API__declspec(dllexport)
#否则
#定义DLL00\u导出\u API
#恩迪夫
typedef void(*回调)(未签名字符*pData,int len);
#如果已定义(uuu cplusplus)
外部“C”{
#恩迪夫
DLL00_EXPORT_API void dll00Func00(回调cb、无符号整数len、无符号字符填充值);
#如果已定义(uuu cplusplus)
}
#恩迪夫
void dll00Func00(回调cb、无符号整数len、无符号字符填充值){
无符号字符*pData=malloc(len);
memset(pData、fillValue、len);
cb(pData,len);
免费(pData);
pData=NULL;
}
代码00.py:

#/usr/bin/env python
导入系统
将ctypes导入为ct
CharArray=ct.POINTER(ct.c#char)#1:使用ct.POINTER(ct.c#char)代替ct.c#char作为第二个参数类型
#CharArray=ct.c\u char\p
Callback=ct.CFUNCTYPE(无、字符、ct.c_int)
DLL_NAME=“./dll00.DLL”
数据长度=0x100
def func(数据,长度):
打印(“长度:{0:d}”。格式(长度))
打印(类型(数据))
打印(“元素:”)
对于[0,数据长度-1]中的idx:
打印(“{0:3d}-{1:}”。格式(idx,数据[idx]))
b=b“”。连接((数据[i]表示范围(长度)中的i)
打印(类型(b)、透镜(b)、b)
def主(*argv):
dll00=ct.CDLL(DLL\u名称)
dll00Func00=dll00.dll00Func00
dll00Func00.argtypes=(回调,ct.c_uint,ct.c_ubyte)
dll00Func00.restype=None
dll00Func00(Callback(func),DATA_LEN,0xAA)###2:将0x00作为第三个参数传递并取消注释行#8,您将看到我在第一个注释中的意思
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{0:s}{1:d}位在{2:s}\n.format(“.”join(sys.version.split(“\n”)中的elem的elem.strip()),如果sys.maxsize>0x100000000,则为64,否则为32,sys.platform))
main(*sys.argv[1:])
打印(“\n完成”)
输出

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q063190506]>sopr.bat
***设置较短的提示,以便粘贴到StackOverflow(或其他)页面时更适合***
[提示]>“c:\Install\pc032\Microsoft\VisualStudioCommunity\2017\VC\Auxiliary\Build\vcvarsall.bat”x64
**********************************************************************
**Visual Studio 2017开发者命令提示符v15.9.25
**版权所有(c)2017微软公司
**********************************************************************
[vcvarsall.bat]环境已初始化为:“x64”
[提示]>dir/b
代码00.py
dll00.c
[提示]>cl/nologo/MD/DDLL dll00.c/link/nologo/DLL/OUT:dll00.DLL
dll00.c
创建库dll00.lib和对象dll00.exp
[提示]>dir/b
代码00.py
dll00.c
dll00.dll
dll00.exp
dll00.lib
dll00.obj
[提示]>
[提示]>“e:\Work\Dev\VEnvs\py\u pc064\u 03.07.06\u test0\Scripts\python.exe”code00.py
win32上的Python 3.7.6(tags/v3.7.6:43364a7ae0,2019年12月19日,00:42:30)[MSC v.1916 64位(AMD64)]64位
长度:256
元素:
0-b'\xaa'
255-b'\xaa'
256\\xa A A A A A A A \ \ \ \xa A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A \ \ \ \ \ \ \ \ \ \ \xa A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A a\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\XA A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa'
完成。
注释

  • c_char_p将与NUL终止的字符串一起使用,在这里使用它将是不正确的(即使看起来一切正常)
  • 这个例子有点复杂(为了方便地举例说明前面的项目符号)
列表

这个问题有点不清楚。给定现有代码,您应该已经在回调函数中将数据作为字节

这里有一个例子

dll00.c:

#包括
#包括
#如果已定义(_WIN32)
#定义DLL00_导出_API__declspec(dllexport)
#否则
#定义DLL00\u导出\u API
#恩迪夫
typedef void(*回调)(未签名字符*pData,int len);
#如果已定义(uuu cplusplus)
外部“C”{
#恩迪夫
DLL00_EXPORT_API void dll00Func00(回调cb、无符号整数len、无符号字符填充值);
#如果已定义(uuu cplusplus)
}
#恩迪夫
void dll00Func00(回调cb、无符号整数len、无符号字符填充值){
无符号字符*pData=malloc(len);
memset(pData、fillValue、len);
cb(pData,len);
免费(pData);
pData=NULL;
}
代码00.py:

#/usr/bin/env python
导入系统
将ctypes导入为ct
CharArray=ct.POINTER(ct.c#char)#1:使用ct.POINTER(ct.c#char)代替ct.c#char作为第二个参数类型
#CharArray=ct.c\u char\p
Callback=ct.CFUNCTYPE(无、字符、ct.c_int)
DLL_NAME=“./dll00.DLL”
数据长度=0x100
def func(数据,长度):
打印(“长度:{0:d}”。格式(长度))
打印(类型(数据))
打印(“元素:”)
对于[0,数据长度-1]中的idx:
打印(“{0:3d}-{1:}”.fo