调用函数作为ctypes中其他函数的指针返回

时间:2011-09-23 19:32:11

标签: python function-pointers ctypes

我正在尝试使用ctypes来调用作为来自另一个函数的指针返回的c函数。从文档中可以看出,我可以通过使用CFUNCTYPE声明函数,然后使用指针创建实例来实现此目的。然而,这似乎给了我一个段错误。这是一些示例代码。

sample.c文件:

#include <stdio.h>

unsigned long long simple(void *ptr)
{
  printf("pointer = %p\n", ptr);
  return (unsigned long long)ptr;
}

void *foo()
{
  return (void *)simple;
}

unsigned long long (*bar)(void *ptr) = simple;

int main() 
{
  bar(foo());
  simple(foo());
}

和simple.py:

from ctypes import *
import pdb

_lib = cdll.LoadLibrary('./simple.so')

_simple = _lib.simple
_simple.restype = c_longlong
_simple.argtypes = [ c_void_p ]

_foo = _lib.foo
_bar = CFUNCTYPE(c_int, c_void_p)(_foo())

pdb.set_trace()
_bar(_foo())

这是一个gdb / pdb会话:

(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /usr/bin/python simple.py
[Thread debugging using libthread_db enabled]
> .../simple.py(15)<module>()
-> _bar(_foo())
(Pdb) p _foo()
-161909044
(Pdb) cast(_bar,c_void_p).value
18446744073547642572L
(Pdb) _simple(_foo())
pointer = 0xfffffffff65976cc
-161909044
(Pdb) int('fffffffff65976cc',16)
18446744073547642572L

奇怪的是,如果我使用C main函数运行,我会得到

$ ./simple
pointer = 0x400524
pointer = 0x400524

与我从python代码中获得的指针不匹配。

我在这里做错了什么?

提前感谢您提供任何指导!

1 个答案:

答案 0 :(得分:2)

您没有为_foo定义任何返回类型,请尝试添加:

_foo.restype = c_void_p

ctypes默认为int returntype,它看起来(来自你在pdb会话中完成的转换)就像你在64位系统上一样意味着你的指针在转换为int时会被截断。在我的系统上代码似乎工作 - 但这是一个32位系统(不幸的是我现在没有任何64位系统可供测试)。

另外你的_bar定义与C代码中的内容并不匹配,我建议使用类似的东西:

_bar = CFUNCTYPE(c_longlong, c_void_p).in_dll(_lib, "bar")