C++ - Python 与 ctypes 绑定 - Return 函数中的多个值
C++ - Python Binding with ctypes - Return multiple values in function
我找到了这个 C++ Python 绑定的例子:
Calling C/C++ from python?
根据那里的答案,我创建了一些测试文件:
foo.cpp:
#include <iostream>
#include <utility>
int bar_2(int a, int b){
return a*b;
}
std::pair<int, int> divide(int dividend, int divisor)
{
return std::make_pair(dividend / divisor, dividend % divisor);
}
extern "C" {
int bar_2_py(int a, int b){ return bar_2(a,b); }
std::pair<int, int> divide_py(int d, int div){return divide(d,div);}
}
fooWrapper.py:
#!/usr/bin/env python
from ctypes import cdll
lib = cdll.LoadLibrary('./libfoo.so')
def bar_2(a, b):
res = lib.bar_2_py( a,b )
return res
def divide(d,div):
res = lib.divide_py(d,div)
return res
然后
g++ -c -fPIC foo.cpp -o foo.o
g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
创建libfoo.so
如果我导入它和 运行 iPython 中的函数,我得到函数 "bar_2" 的正确值,但 "divide" 的(部分)错误答案:
from fooWrapper import bar_2, divide
bar_2(10,2) # returns 20, which is right
divide(10,3) # returns 3
显然,return-值是该对的第一个值(因为 10/3 整数除法是 3)。但是第二个价值正在丢失。
那么,获取多个值(在本例中为 2 个整数值)的最佳做法是什么?
谢谢!
我认为 ctypes
不允许在没有太多样板代码的情况下将 std::pair
转换为 python 元组。特别是因为 std::pair
是 c++11
标准的一个特性,而 ctypes
只适用于 c
风格的函数 [需要引用/验证]。
我建议使用 输出参数 ,c
方法来 return 多个值。这个想法很简单,c
-函数 returns 它是指针的值,example.c
:
void divide_modulo(int a, int b, int *div, int *rest)
{
*div = a / b;
*rest = a % b;
}
然后编译成共享库:
gcc -o libexample.so -shared example.c
libexample.so
现在允许您通过 c
中的指针写入 python 整数,这些指针作为参数传递,如下所示:
import ctypes
lib = ctypes.cdll.LoadLibrary('./libexample.so')
def divide_modulo(a, b):
div = ctypes.c_int(0)
rest = ctypes.c_int(0)
lib.divide_modulo(a, b, ctypes.byref(div), ctypes.byref(rest))
return (div.value, rest.value)
print(divide_modulo(11, 4))
当使用 div
和 rest
调用 lib.divide_modulo
时,ctypes.byref
包装器将 int
转换为指向 int
的指针。
我找到了这个 C++ Python 绑定的例子: Calling C/C++ from python? 根据那里的答案,我创建了一些测试文件:
foo.cpp:
#include <iostream>
#include <utility>
int bar_2(int a, int b){
return a*b;
}
std::pair<int, int> divide(int dividend, int divisor)
{
return std::make_pair(dividend / divisor, dividend % divisor);
}
extern "C" {
int bar_2_py(int a, int b){ return bar_2(a,b); }
std::pair<int, int> divide_py(int d, int div){return divide(d,div);}
}
fooWrapper.py:
#!/usr/bin/env python
from ctypes import cdll
lib = cdll.LoadLibrary('./libfoo.so')
def bar_2(a, b):
res = lib.bar_2_py( a,b )
return res
def divide(d,div):
res = lib.divide_py(d,div)
return res
然后
g++ -c -fPIC foo.cpp -o foo.o
g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
创建libfoo.so
如果我导入它和 运行 iPython 中的函数,我得到函数 "bar_2" 的正确值,但 "divide" 的(部分)错误答案:
from fooWrapper import bar_2, divide
bar_2(10,2) # returns 20, which is right
divide(10,3) # returns 3
显然,return-值是该对的第一个值(因为 10/3 整数除法是 3)。但是第二个价值正在丢失。
那么,获取多个值(在本例中为 2 个整数值)的最佳做法是什么?
谢谢!
我认为 ctypes
不允许在没有太多样板代码的情况下将 std::pair
转换为 python 元组。特别是因为 std::pair
是 c++11
标准的一个特性,而 ctypes
只适用于 c
风格的函数 [需要引用/验证]。
我建议使用 输出参数 ,c
方法来 return 多个值。这个想法很简单,c
-函数 returns 它是指针的值,example.c
:
void divide_modulo(int a, int b, int *div, int *rest)
{
*div = a / b;
*rest = a % b;
}
然后编译成共享库:
gcc -o libexample.so -shared example.c
libexample.so
现在允许您通过 c
中的指针写入 python 整数,这些指针作为参数传递,如下所示:
import ctypes
lib = ctypes.cdll.LoadLibrary('./libexample.so')
def divide_modulo(a, b):
div = ctypes.c_int(0)
rest = ctypes.c_int(0)
lib.divide_modulo(a, b, ctypes.byref(div), ctypes.byref(rest))
return (div.value, rest.value)
print(divide_modulo(11, 4))
当使用 div
和 rest
调用 lib.divide_modulo
时,ctypes.byref
包装器将 int
转换为指向 int
的指针。