我目前正在为相机软件编写python绑定。商业SDK仅包含文档和DLL。我没有C代码,但我会尽量清楚,所以请耐心等待。
我让所有的库函数都工作但只有一个:一个获取图片的回调函数。该文档仅提供函数原型:
foo:在指定端口上启动图像采集。返回错误代码。
int foo(HANDLE dev, char port, int queueMode, callback_type fnCallback, void * userInfo );
callback_type:接收的应用程序定义的回调函数 有关获得的框架的信息。
void callback_type(void * userInfo, photoStruct* photo);
这是我加载库并包装函数和结构后的python代码。
callback_type = WINFUNCTYPE(None,c_void_p,POINTER(photoStruct))
def my_callback(userInfo, photoInfo):
if(photoInfo.status == 0):
#Process incoming photo
print "I'm here" #for debugging purposes
q.put(photoInfo.rawBuffer[:photoInfo.bufferSize])
q.task_done()
_my_callback = callback_type(my_callback)
每当我第一次尝试打电话给foo时:
>>>lib.foo(dev, port, c_int(0), _my_callback, None)
我收到错误代码4:没有足够的内存来执行操作(根据文档)。 当我再次(再次)调用它时,它总是返回0,这是成功的,但是队列保持为空并且它从不打印"我在这里"。
然后我尝试添加一个帖子:
ty = threading.Thread(target=lib.foo, args=(dev,port, c_int(0), _my_callback, None))
>>> ty.start()
>>> ty.run()
line 758, in run
del self.__target, self.__args, self.__kwargs
AttributeError: _Thread__target
我也尝试过不使用run()并在启动线程后直接调用该函数。它还没有工作。 我真的不知道这里发生了什么。我对线程和ctypes很新,但我的猜测是库使用自己的线程来返回照片,我不知何故应该为这个回调函数分配内存。但是怎么样? 任何解决方案/评论将不胜感激。谢谢!
_编辑:文档中的示例代码_
* \sample
* \code
* void __stdcall callback_type(void* userInfo, photoStruct* photo)
* {
* // Process incoming photo
* }
* ...
* foo(dev, port, 0, &callback_type, NULL);
* ...
* \endcode
*/
我尝试使用
在Python中调用foo>>>lib.foo(dev, port, c_int(0), byref(_my_callback), None)
它停止了该计划。
答案 0 :(得分:1)
如果没有完整的例子,我不确定你哪里出错了。你宣布foo.argtypes
了吗?您确定这些函数__stdcall
适用于WinDLL
和WINFUNCTYPE
,还是__cdecl
且需要CDLL
和CFUNCTYPE
?
这是一个使用DLL的以下测试代码的工作示例:
typedef void* HANDLE;
typedef struct {
int value;
} photoStruct;
typedef void (__stdcall * callback_type)(void * userInfo, photoStruct* photo);
__declspec(dllexport) int __stdcall foo(HANDLE dev, char port, int queueMode, callback_type fnCallback, void * userInfo)
{
photoStruct p;
p.value = 123;
fnCallback(userInfo, &p);
return 0;
}
Python代码:
#!python2
from ctypes import *
HANDLE = c_void_p
class photoStruct(Structure):
_fields_ = [('value',c_int)]
def __repr__(self):
return 'photoStruct(value={})'.format(self.value)
callback_type = WINFUNCTYPE(None,c_void_p,POINTER(photoStruct))
@callback_type
def my_callback(userInfo, photo):
print userInfo,photo.contents
foo = WinDLL('test').foo
foo.argtypes = (HANDLE,c_char,c_int,callback_type,c_void_p)
foo.restype = c_int
foo(1,'2',3,my_callback,None)
输出:
None photoStruct(value=123)