Python无法使用Python的ctypes

时间:2017-07-17 03:20:36

标签: python c python-3.x dll ctypes

我在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这里的相关问题,我想我不应该在这里按值返回结构,因为返回的结构是实现定义的。

2 个答案:

答案 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上使用它进行计算   [这可以避免工作问题]。