将来自 C 函数的指针参数与 python 脚本中的 ctype 参数链接起来
Linking pointer arguments from a C function with a ctype argument in python script
下面是一个简单的数字除法代码:
//pointer.h
#include<stdio.h>
int divide(int , int , int *);
//pointer.c
#include<stdio.h>
__declspec(dllexport) int divide(int a, int b, int *remainder)
{
int quot = a / b;
remainder = a % b;
return quot;
}
如pointer.c所示,余数是一个指针类型的参数,其值将在函数本身中计算。谁能告诉我如何获取从该函数链接到 python 脚本的值,如下所示:
//python script
import ctypes as C
from ctypes import *
mydll=CDLL('pointer.dll')
mydll.divide.argtypes=(C.c_int,C.c_int,C.POINTER(C.c_int))
mydll.divide.restype=C.c_int
以下是我遇到的错误。
mydll.divide(4,32,3)
Traceback (most recent call last):
File "", line 1, in
mydll.divide(4,32,3)
ctypes.ArgumentError: argument 3: : expected LP_c_long instance instead of int
编辑
您似乎在用三个整数参数 (mydll.divide(4,32,3)
) 调用包装的除法函数。那行不通的。请参阅下面的代码,了解您可能希望如何指定第三个参数。我的 post 的其余部分可能是不必要的,但无论如何我都会把它留给未来遇到不同问题的读者。
我首先要确保您使用与 python 发行版相同的位数来编译 DLL(例如 32 位与 64 位)。
接下来,您的代码有一个错误,即 remainder = a % b;
应该是 *remainder = a % b;
(大概您是从 here 开始工作的。)
最后,以下代码对我有用(在 Linux 下,因此使用 gcc 和 .so 文件而不是 .dll 文件):
pointer.c
#include<stdio.h>
int divide(int a, int b, int *remainder)
{
int quot = a / b;
*remainder = a % b;
return quot;
}
test.py
import ctypes as C
from ctypes import *
mydll=CDLL('pointer.so')
mydll.divide.argtypes=(C.c_int, C.c_int, C.POINTER(C.c_int))
mydll.divide.restype=C.c_int
rem = C.c_int()
res = mydll.divide(10, 3, rem)
print(res, rem.value)
当 运行 时,这会正确打印 (3, 1)
。
备注:
- 使用 gcc,编译为:
gcc -g -Wall -shared -fPIC -I/usr/include/python2.7/ pointer.c -o pointer.so
- 我能够删除
__declspec
因为 gcc exports all symbols by default,如果您使用不同的编译器,您可能需要保留它。
- 我没有使用 .h 文件
下面是一个简单的数字除法代码:
//pointer.h
#include<stdio.h>
int divide(int , int , int *);
//pointer.c
#include<stdio.h>
__declspec(dllexport) int divide(int a, int b, int *remainder)
{
int quot = a / b;
remainder = a % b;
return quot;
}
如pointer.c所示,余数是一个指针类型的参数,其值将在函数本身中计算。谁能告诉我如何获取从该函数链接到 python 脚本的值,如下所示:
//python script
import ctypes as C
from ctypes import *
mydll=CDLL('pointer.dll')
mydll.divide.argtypes=(C.c_int,C.c_int,C.POINTER(C.c_int))
mydll.divide.restype=C.c_int
以下是我遇到的错误。
mydll.divide(4,32,3) Traceback (most recent call last): File "", line 1, in mydll.divide(4,32,3) ctypes.ArgumentError: argument 3: : expected LP_c_long instance instead of int
编辑
您似乎在用三个整数参数 (mydll.divide(4,32,3)
) 调用包装的除法函数。那行不通的。请参阅下面的代码,了解您可能希望如何指定第三个参数。我的 post 的其余部分可能是不必要的,但无论如何我都会把它留给未来遇到不同问题的读者。
我首先要确保您使用与 python 发行版相同的位数来编译 DLL(例如 32 位与 64 位)。
接下来,您的代码有一个错误,即 remainder = a % b;
应该是 *remainder = a % b;
(大概您是从 here 开始工作的。)
最后,以下代码对我有用(在 Linux 下,因此使用 gcc 和 .so 文件而不是 .dll 文件):
pointer.c
#include<stdio.h>
int divide(int a, int b, int *remainder)
{
int quot = a / b;
*remainder = a % b;
return quot;
}
test.py
import ctypes as C
from ctypes import *
mydll=CDLL('pointer.so')
mydll.divide.argtypes=(C.c_int, C.c_int, C.POINTER(C.c_int))
mydll.divide.restype=C.c_int
rem = C.c_int()
res = mydll.divide(10, 3, rem)
print(res, rem.value)
当 运行 时,这会正确打印 (3, 1)
。
备注:
- 使用 gcc,编译为:
gcc -g -Wall -shared -fPIC -I/usr/include/python2.7/ pointer.c -o pointer.so
- 我能够删除
__declspec
因为 gcc exports all symbols by default,如果您使用不同的编译器,您可能需要保留它。 - 我没有使用 .h 文件