Python 使用ctypes调用带有dll/so中引用参数的cpp函数的正确方法是什么?
我知道在dll/so中调用cpp函数是不合适的,例如,Python 使用ctypes调用带有dll/so中引用参数的cpp函数的正确方法是什么?,python,ctypes,Python,Ctypes,我知道在dll/so中调用cpp函数是不合适的,例如,ctpyes调用的intfoo(int&),因为c中没有等效的参考变量概念。但是我想展示一个演示,我对python的行为(版本3.7)感到非常困惑 基本上,我有一个来自其他人的DLL,我相信它是由VS C++构建的,并使用外“C”< /COD>导出。dll中有一些接口的形式为intfoo(int&)。当我使用python时,我需要一个ctypes层来包装它。比如说, int foo(int&) 转换为(\u foo由ctypes加载
ctpyes
调用的intfoo(int&)
,因为c
中没有等效的参考变量概念。但是我想展示一个演示,我对python的行为(版本3.7)感到非常困惑
基本上,我有一个来自其他人的DLL,我相信它是由VS C++构建的,并使用<代码>外“C”< /COD>导出。dll中有一些接口的形式为
intfoo(int&)
。当我使用python时,我需要一个ctypes
层来包装它。比如说,
int foo(int&)
转换为(\u foo由ctypes
加载)
我像python一样调用foo
i = c_int(1)
_foo(i)
它是有效的。
我用linux中的一个演示进一步测试了以下代码
demo.cpp
#include <stdio.h>
extern "C" int foo(int&);
int foo(int& i)
{
printf("foo is called.\n");
printf("Got i: %d\n", i);
i += 10;
printf("Set i: %d\n", i);
return 0;
}
因此,构建了一个libdemo.So
demo.py
#!/usr/bin/env python3
from ctypes import CDLL, c_int,POINTER
l = CDLL("libdemo.so")
_foo = l.foo
_foo.argtypes = [POINTER(c_int)]
_foo.restype = c_int
def foo(i):
print("Input: i",i)
_i = c_int(i)
r = _foo(_i)
i = _i.value
print("Output: i", i)
foo(1)
如果我运行demo.py
LD_LIBRARY_PATH=. ./demo.py
它将很好地工作,并给我正确的答案,即
Input: i 1
foo is called.
Got i: 1
Set i: 11
Output: i 11
如果我通过byref
传递i
,则将demo.py
更改为
#!/usr/bin/env python3
from ctypes import CDLL, c_int,POINTER,byref
l = CDLL("libdemo.so")
_demo = l.demo
_demo.argtypes = [PONTER(c_int)]
_demo.restype = c_int
def demo(i):
print("Input: i",i)
_i = c_int(i)
r = _demo(byref(_i)) # calling by byref
i = _i.value
print("Output: i", i)
demo(1)
它仍按原样工作,输出相同
那么,引擎盖下发生了什么?为什么上面两个版本的demo.py
具有相同的输出?我是否可以依靠此功能使用ctpyes
调用可以引用参数的cpp函数
Input: i 1
foo is called.
Got i: 1
Set i: 11
Output: i 11
#!/usr/bin/env python3
from ctypes import CDLL, c_int,POINTER,byref
l = CDLL("libdemo.so")
_demo = l.demo
_demo.argtypes = [PONTER(c_int)]
_demo.restype = c_int
def demo(i):
print("Input: i",i)
_i = c_int(i)
r = _demo(byref(_i)) # calling by byref
i = _i.value
print("Output: i", i)
demo(1)