我在C中写了一个小dll,这是我的.c文件。
struct my_struct
{
char arr[3];
};
__declspec(dllexport) struct my_struct func()
{
struct my_struct m;
m.arr[0] = 1;
m.arr[1] = 2;
m.arr[2] = 3;
return m;
};
//compiled to testdll.dll
我尝试使用python调用导出的c函数。这是我的.py文件。
from ctypes import *
class MyStruct(Structure):
_fields_ = [("arr", c_char * 3)]
f = cdll.testdll.func
f.restype = MyStruct
for i in f().arr:
print(i)
当我尝试在返回的c结构中读取数组时,我总是得到随机值。
但是如果我在.cpp和.py文件中使用int数组而不是char数组,我可以按预期获得正确的值。为什么呢?
Error when using ctypes module to acess a DLL written in C这里的相关问题,我想我不应该在这里按值返回结构,因为返回的结构是实现定义的。
答案 0 :(得分:1)
我能够通过将返回类型声明为POINTER(MyStruct)
来获取正确的值,因此似乎Python将返回结构视为返回指向该结构的指针。返回结构的更自然的方法是将其作为输出参数返回。我举两个例子。
正如您所述,使用func.restype = MyStruct
正确使用c_int * 3
作为结构成员,但我发现func.restype = POINTER(MyStruct)
和c_char * 3
成员只有c_int * 3
当结构用作返回值时。
<强> test.c的强>
struct my_struct
{
char arr[3];
};
__declspec(dllexport) struct my_struct func()
{
struct my_struct m = {1,2,3};
return m;
};
__declspec(dllexport) void func2(struct my_struct* m)
{
m->arr[0] = 4;
m->arr[1] = 5;
m->arr[2] = 6;
};
<强> test.py 强>
from ctypes import *
class MyStruct(Structure):
_fields_ = ('arr',c_char * 3),
dll = CDLL('test')
func = dll.func
func.argtypes = None
func.restype = POINTER(MyStruct)
func2 = dll.func2
func2.argtypes = POINTER(MyStruct),
func2.restype = None
x = func()
print(x.contents.arr[0],x.contents.arr[1],x.contents.arr[2])
m = MyStruct()
func2(m)
print(m.arr[0],m.arr[1],m.arr[2])
<强>输出强>
1 2 3 4 5 6
答案 1 :(得分:1)
如果你不使用Visual Studio,你将面临使用python连接c / c ++ DLL的问题。有时候你的代码很小便可能会出现问题.MinGW [我没有使用过Clang]面临的问题是DLL已经形成但是它的编码与预期的不同。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85).aspx
以下是Windows可移植可执行(PE)标头结构的链接
只有Visual Studio [截至目前]才能生成Windows可执行文件共享库。
如果使用Linux系统,问题将不会持续存在。我不了解Macintosh。
尽管代码很多,但您需要将指针添加到 结构MyStruct,您将在Dll上使用它进行计算 [这可以避免工作问题]。