Python 到 .cpp 并通过 .so 使用 ctypes 再次返回
Python to .cpp and back again with ctypes via an .so
我正在做一些愚蠢的事情,但没有看到什么...我已将我的问题简化为以下(荒谬的)示例 - 但它突出显示了我的问题所在 - 我显然无法传递数据从 c++ 连贯地进入 and/or return。
test.cpp
extern "C"
double reflect(double inp){
return inp;
}
以上编译为:
g++ -c -Wall - Werror -fPIC test.cpp -o testO.o
g++ -shared -o testSO.so testO.o
仅包含输出文件定义,因为我会在实际问题中使用它们
.py
import ctypes
hdl = ctypes.cdll.LoadLibrary(r"C:\Windows\path\to\testSO.so")
所以,我的 return
hdl.reflect(1)
>>> 1 (no ctypes conversion, but erm, OK)
hdl.reflect(1.1)
>>> Failure (this is expected)
hdl.reflect(ctypes.c_int(1))
>>> 1 (right well, c_int to c_double looks like it could implicitly work)
hdl.reflect(ctypes.c_float(1.1))
>>> 1006192077 (WTF?!?)
hdl.reflect(ctypes.c_double(1.2))
>>> 858993459 (WTF?!?!)
OS 是 windows 10,编译器是 minGW-W64 8.1.0,python 是 3.8 (anaconda)
我之前有 运行 个 DLL,并且我之前已经将我自己的 .c 编译成 python 模块 - 但对于我来说,我看不出我在这里做错了什么。 ....!?!
编辑:更正了拓扑排序指出的拼写错误(.so 的路径在代码中是正确的,此处缺少尾随 ")
目标文件和共享库不包含任何关于函数参数类型或 return 类型的信息,至少对于 C 链接函数是这样。
因此 ctypes
无法知道该函数应该采用 double
参数和 return 一个 double
.
如果你用 ctypes.c_double
以外的任何东西作为参数调用它,你将有未定义的行为。但是您可以将参数类型设置为自动转换为正确的 ctypes
类型(见下文)。
ctypes
还假设 return 类型是 int
。如果不是这种情况,您应该在调用之前正确设置 return 类型。在下文中,我还设置了参数类型,以便 ctypes
在调用中自动使用正确的类型:
reflect = hdl.reflect
reflect.argtypes = [ctypes.c_double]
reflect.restype = ctypes.c_double
reflect(1.2)
我正在做一些愚蠢的事情,但没有看到什么...我已将我的问题简化为以下(荒谬的)示例 - 但它突出显示了我的问题所在 - 我显然无法传递数据从 c++ 连贯地进入 and/or return。
test.cpp
extern "C"
double reflect(double inp){
return inp;
}
以上编译为:
g++ -c -Wall - Werror -fPIC test.cpp -o testO.o
g++ -shared -o testSO.so testO.o
仅包含输出文件定义,因为我会在实际问题中使用它们
.py
import ctypes
hdl = ctypes.cdll.LoadLibrary(r"C:\Windows\path\to\testSO.so")
所以,我的 return
hdl.reflect(1)
>>> 1 (no ctypes conversion, but erm, OK)
hdl.reflect(1.1)
>>> Failure (this is expected)
hdl.reflect(ctypes.c_int(1))
>>> 1 (right well, c_int to c_double looks like it could implicitly work)
hdl.reflect(ctypes.c_float(1.1))
>>> 1006192077 (WTF?!?)
hdl.reflect(ctypes.c_double(1.2))
>>> 858993459 (WTF?!?!)
OS 是 windows 10,编译器是 minGW-W64 8.1.0,python 是 3.8 (anaconda)
我之前有 运行 个 DLL,并且我之前已经将我自己的 .c 编译成 python 模块 - 但对于我来说,我看不出我在这里做错了什么。 ....!?!
编辑:更正了拓扑排序指出的拼写错误(.so 的路径在代码中是正确的,此处缺少尾随 ")
目标文件和共享库不包含任何关于函数参数类型或 return 类型的信息,至少对于 C 链接函数是这样。
因此 ctypes
无法知道该函数应该采用 double
参数和 return 一个 double
.
如果你用 ctypes.c_double
以外的任何东西作为参数调用它,你将有未定义的行为。但是您可以将参数类型设置为自动转换为正确的 ctypes
类型(见下文)。
ctypes
还假设 return 类型是 int
。如果不是这种情况,您应该在调用之前正确设置 return 类型。在下文中,我还设置了参数类型,以便 ctypes
在调用中自动使用正确的类型:
reflect = hdl.reflect
reflect.argtypes = [ctypes.c_double]
reflect.restype = ctypes.c_double
reflect(1.2)