将c结构返回到python时出错

2024-05-31 23:41:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个c函数:

extern "C"  __declspec(dllexport) MyStruct foo()
{
    MyStruct s = {0, 0}
    return s;
}

其中MyStruct定义为:

^{pr2}$

我尝试在python中调用函数,但总是出现以下错误:

WindowsError: exception: access violation writing 0x00000000

如果我从结构中删除void*c,那么它可以工作。。。在

那么我应该如何返回空指针呢? 谢谢!在


Tags: 函数return定义accessfoo错误exceptionextern
3条回答

如果Python代码有帮助的话。您需要定义foo的结构和返回类型:

from ctypes import *

class MyStruct(Structure):
    _fields_ = [
        ('a',c_int),
        ('b',c_int),
        ('c',c_void_p)]

mydll = CDLL('mydll')
mydll.foo.restype = MyStruct

r = mydll.foo()
print r.a
print r.b
print r.c

这几乎可以肯定是由C编译器和ABI上用于返回对象的ctypes库不一致造成的。在没有看到Python代码的情况下,很难说问题是由于返回类型的Python声明不正确、ctypes库中的错误还是C编译器选择的非标准ABI造成的。在

我建议通过一个可移植的函数返回一个可移植的对象:

extern "C"  __declspec(dllexport) void foo(MyStruct *ret)
{
    MyStruct s = {0, 0}
    *ret = s;
}

和它的接口是这样的:

^{pr2}$

我看不出你在分配你的void*c。我在任何地方都看不到这一点,但它似乎是在稍后的某个地方被读取的(例如,access violation writing 0x00000000,一个空指针)。因此,c需要在取消引用之前初始化为某个值。在

似乎c的值正好是0,但它不是必须的。它没有静态存储持续时间,而且您没有初始化它(您只使用{0, 0}初始化a和{}),因此{}可以有任何值。在我的测试用例中,c位于已初始化为0的内存区域中(即使是在发行版中)。这不能保证。在

我敢打赌你是在做这样的事情:

MyStruct s = foo();
*((some_type*)s.c) = some_value;  // BLAMOOO! c is uninitialized

你还没有发布使用返回值的代码,所以这是我能给你的最好的猜测。在

相关问题 更多 >