从ctypes中的其他函数作为指针返回的调用函数 [英] calling functions returned as pointers from other functions in ctypes

查看:105
本文介绍了从ctypes中的其他函数作为指针返回的调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use ctypes to call a c function that was returned as a pointer from another function. It seems from the documentation that I can do this by declaring the function with CFUNCTYPE, and then creating an instance using the pointer. This, however seems to give me a segfault. Here is some sample code.

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:

and 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会话:

Here's a gdb/pdb session:

(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函数运行,我会得到

Curiously, if I run using the C main function, I get

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

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

which doesn't match the pointer that I get from the python code.

我在这里做什么错了?

预先感谢您可以提供的任何指导!

Thanks in advance for any guidance you can give!

推荐答案

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

You are not defining any return type for _foo, try adding:

_foo.restype = c_void_p

ctypes默认为int returntype,并且看起来(从您在pdb会话中完成的转换)就像您在64位系统上一样,这意味着在conv时指针将被截断设置为int。在我的系统上,代码似乎可以正常工作-但这是一个32位系统(很遗憾,我现在没有任何64位系统可用于测试)。

ctypes defaults to int returntype, and it looks (from the cast done in you pdb session) like you are on a 64-bit system meaning that you pointer will be truncated when converted to int. On my system the code seems to work - but that is a 32-bit system (and unfortunately I don't have any 64-bit system available to test on right now).

另外,您_bar的定义与C代码中的不完全匹配,我建议使用类似以下内容的东西:

Also you _bar definition doesn't really match what is in the C code, I suggest using something like:

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

这篇关于从ctypes中的其他函数作为指针返回的调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆