[英]How to pass a binary buffer via python ctypes to a c function
I'd like to wrap the following c function bar() in python 2.x and invoke it via the ctypes module, both on Linux and Windows: 我想将以下c函数bar()包装在python 2.x中,并在Linux和Windows上通过ctypes模块调用它:
#include <stdio.h>
#ifdef FOO_DLL
#define FOO_API __declspec(dllexport)
#else
#define FOO_API extern
#endif
FOO_API unsigned int bar(const void* data, unsigned int len)
{
printf("%p (%d bytes)\n", data, len);
return len;
}
To compile the shared library I use scons: 要编译共享库,我使用scons:
import sys
env = Environment()
if sys.platform == 'win32':
env.Append(CFLAGS=['-DFOO_DLL'])
env.SharedLibrary('foo', ['foo.c'])
Finally I load the respective shared lib and invoke the function: 最后,我加载各自的共享库并调用该函数:
import sys
import struct
from ctypes import *
if sys.platform == 'win32':
libfoo = windll.LoadLibrary('foo')
else:
libfoo = cdll.LoadLibrary('./libfoo.so')
data = struct.pack('BBB', 0, 1, 2)
libfoo.bar(data, len(data))
To my surprise this seems to work flawlessly under Linux, but on Windows the code throws an error that makes me suspects that this isn't the proper way to do things: 令我惊讶的是,这似乎在Linux下可以完美地工作,但是在Windows上,代码引发了一个错误,使我怀疑这不是正确的处理方式:
$ python foo.py
00B520C4 (3 bytes)
Traceback (most recent call last):
File "foo.py", line 11, in <module>
libfoo.bar(data, len(data))
ValueError: Procedure probably called with too many arguments (8 bytes in excess)
What would be the right approach? 什么是正确的方法?
On Linux (Ubuntu 10.10 64bit) I'm using Python 2.6.6, gcc 4.4.5 and on Windows (XP 32bit, in a VirtualBox) Python 2.7.1 and VS2010 Express. 在Linux(Ubuntu 10.10 64位)上,我使用的是Python 2.6.6,gcc 4.4.5,在Windows(XP 32位,在VirtualBox中)使用的是Python 2.7.1和VS2010 Express。
Both Windows and Linux should use cdll
which results in the C calling convention. Windows和Linux都应使用
cdll
,这将导致C调用约定。 The Python code at present calls your Windows DLL using stdcall
but it's really a cdecl
function. 目前,Python代码使用
stdcall
调用Windows DLL,但这实际上是一个cdecl
函数。 The difference between cdll
and windll
is just the calling convention used. cdll
和windll
之间的区别只是所使用的调用约定。
That error message is a textbook calling convention mismatch error, for what it's worth. 该错误消息是一本教科书,称其约定不匹配错误,这是值得的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.