gpt4 book ai didi

python - C++ - Python 与 ctypes 的绑定(bind) - 在函数中返回多个值

转载 作者:行者123 更新时间:2023-11-30 02:37:16 28 4
gpt4 key购买 nike

我找到了这个 C++ Python 绑定(bind)示例: 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

显然,返回值是对的第一个值(因为 10/3 int 除法是 3)。但是第二个值(value)正在丢失。

那么,获取多个值(在本例中为 2 个整数值)的最佳做法是什么?

谢谢!

最佳答案

我不认为 ctypes 允许在没有太多样板代码的情况下将 std::pair 转换为 python 元组。特别是 std::pairc++11 标准的一个特性,而 ctypes 只适用于 c 风格的函数 [需要引用/验证]。

我建议使用输出参数c 方法来返回多个值。这个想法很简单,c-函数通过指针返回它的值,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))

使用 divrest 调用 lib.divide_modulo 时,ctypes.byref 包装器将 int 指向指向 int 的指针。

关于python - C++ - Python 与 ctypes 的绑定(bind) - 在函数中返回多个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31835398/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com