如何使用 CTypes 通过引用将数组从 python 传递给 C++ 函数?

How do you pass an array by reference from python to a C++ function using CTypes?

正如标题所说,在过去的 48 小时里,我一直在尝试将向量从 python 项目传递到我编写的一组 C++ 函数中。最终我得出结论,基于对过去帖子的一些阅读,使用数组而不是向量可能更容易。这导致我在下面尝试这个教程,但它最初只是为了举例说明传递一个整数并返回它。我尝试更改代码,以便它通过引用从 python 传递一个 3 长的数字 list/array,然后将其中的每个数字加 1。但是,当我 运行 这个时,我可以看到它正在获取数组没有问题并打印在 c++ 函数中修改的值,但它没有修改原始 python 变量。事实上,当我尝试打印包装函数的输出时,我得到的是“main.c_double_Array_3'>”。以下是我到目前为止尝试过的代码(在当前状态下)。如果有人可以提供有关资源的一些指导,以获得有关如何执行此操作的清晰教程,或者提供一些有关如何操作的帮助,我将不胜感激。

Simple_calculations C++ 文件

extern "C" void our_function(double * numbers) {
    numbers[0] += 1;
    numbers[1] += 1;
    numbers[2] += 1;
    std::cout << numbers[0] << std::endl;
    std::cout << numbers[1] << std::endl;
    std::cout << numbers[2] << std::endl;
}

Python 文件

import os

import ctypes

# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    os.system('g++ -dynamiclib -shared -o simple_calculations.dylib simple_calculations.cpp -std=c++17')

    _sum = ctypes.CDLL('simple_calculations.dylib')
    _sum.our_function.argtypes = (ctypes.POINTER(ctypes.c_double),)

    def our_function(numbers):
        array_type = ctypes.c_double * 3
        _sum.our_function(array_type(*numbers))
        return array_type

    z = our_function([0, 1, 2])

    print(z)

输出

1
2
3
<class '__main__.c_double_Array_3'>

您正在 returnarray_type。那是一个 type,不是类型的实例。该实例是您传递给函数的 array_type(*numbers),但不会保留。将它分配给一个变量和 return that,或者更好的是将它转换回 Python 列表,如下所示:

test.cpp

#ifdef _WIN32
#   define API __declspec(dllexport)
#else
#   define API
#endif

extern "C" API void our_function(double * numbers) {
    numbers[0] += 1;
    numbers[1] += 1;
    numbers[2] += 1;
}

test.py

import ctypes

_sum = ctypes.CDLL('./test')
_sum.our_function.argtypes = ctypes.POINTER(ctypes.c_double),

def our_function(numbers):
    array_type = ctypes.c_double * 3  # equiv. to C double[3] type
    arr = array_type(*numbers)        # equiv. to double arr[3] = {...} instance
    _sum.our_function(arr)  # pointer to array passed to function and modified
    return list(arr)        # extract Python floats from ctypes-wrapped array

z = our_function([0, 1, 2])
print(z)

输出:

[1.0, 2.0, 3.0]