使用ctypes从nullary函数(segfault)x64中获取指针

时间:2014-10-02 23:09:42

标签: python c ctypes

我已将问题减少到以下玩具文件和命令:

// a.c --> a.out, compiled with `gcc -fPIC -shared a.c`
void* r2() {
  return NULL; // <-- could be anything
}

python -i -c "from ctypes import *; clib = cdll.LoadLibrary('/home/soltanmm/tmp/a.out'); CFUNCTYPE(c_void_p).in_dll(clib,'r2')()"

^会在ffi_call_unix64内直接导致调用中的段错误。

我在运行Python 2.7的AMD64 Linux机器上。我做错了什么?

修改

重点指出指针不重要,第二个例子是段错误:

// a.c --> a.out
int r1() {
  return 1;
}

python -i -c "from ctypes import *; clib = cdll.LoadLibrary('/home/soltanmm/tmp/a.out'); CFUNCTYPE(c_int).in_dll(clib,'r1')()"

1 个答案:

答案 0 :(得分:0)

CFUNCTYPE用于回调(或指向共享对象中定义为变量的函数的指针)。执行cdll.LoadLibrary之后,您应该可以直接在返回的库对象上调用C函数。所以这样的事情应该有效:

from ctypes import *;
clib = cdll.LoadLibrary('/home/soltanmm/tmp/a.out');
print(clib.r2())

方法in_dll通常用于访问从共享对象导出的变量。不是功能本身。使用in_dll的示例如下:

档案 a.c

#include <stdlib.h>

int r2() {
    return 101;
}

int (*f)(void) = r2;
char *p = "Hello World";

char *gethw() {
    return p;
}

Python脚本:

from ctypes import *;
clib = cdll.LoadLibrary('/home/soltanmm/tmp/a.out');

# print should call r2() since f is a variable initialized to
# point to function r2 that returns an int. Should 
# print 101
print (CFUNCTYPE(c_int).in_dll(clib,'f')())

# or call r2 directly
print(clib.r2())

# prints out the character (char *) string variable `p'
# should result in 'Hello World' being printed.
print((c_char_p).in_dll(clib,'p').value)

# call the gethw() function that returns a point to a char *
# This too should print 'Hello World'
# we must set the restype c_char_p explicitly since the default
# is to assume functions return `int`
gethw = clib.gethw
gethw.restype = c_char_p
print(gethw())

可以在Python Documentation

中找到有关ctypes用法的更多信息