【问题标题】:Pass integer array by reference using ctypes使用 ctypes 通过引用传递整数数组
【发布时间】:2019-08-04 08:58:55
【问题描述】:

我想从 python 运行一个 C++ 函数,该函数通过引用返回一个 int* 数组并将其转换为 python 列表。

这是示例 C++ 代码:

#include "stdafx.h"
#include <iostream>

#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT int getResponse(int*& hash_list)
{

    std::cout << hash_list << std::endl;

    int* hashes = new int[3];
    hashes[0] = 8;
    hashes[1] = 9;
    hashes[2] = 10;
    hash_list = hashes;

    std::cout << hash_list << std::endl;
    std::cout << *hash_list << std::endl;
    std::cout << *(hash_list + 1) << std::endl;
    std::cout << *(hash_list + 2) << std::endl;

    return 0;
}

DLLEXPORT void testDLL()
{
    std::cout << "DLL can be read" << std::endl;
}

这是我在 python 中的最佳尝试:

from ctypes import cdll, c_int, POINTER, ARRAY, byref

LIB = cdll.LoadLibrary("<path to DLL>")

LIB.testDLL()

func = LIB.getResponse
itype = c_int
func.argtypes = [POINTER(ARRAY(itype,3))]
func.restype = c_int

chashes = (itype * 3)(*[0,1,2])
print(chashes)

func(byref(chashes))

print(chashes)
print(list(chashes))

这是输出:

DLL can be read
<ctypes.c_long_Array_3 object at 0x000001B00FB7FEC8>
0000000100000000
000001B00DB0AC70
8
9
10
<ctypes.c_long_Array_3 object at 0x000001B00FB7FEC8>
[229682288, 432, 2]

这种方法似乎取得了一些成功,但是我认为传递给 C++ 函数的初始数组具有无效条目。然后返回的值无论如何都会被破坏。

ctypes 可以做到这一点吗?任何建议将不胜感激。

我还尝试使用c_void_p 代替ARRAY。在那种情况下,它似乎也可以工作,但我不知道如何将结果指针转换为 python 列表。

【问题讨论】:

  • Cffi 是一个更新的库,可以做同样的工作

标签: python c++ arrays ctypes


【解决方案1】:

ctypes 访问 C 接口。 C 没有指针引用,但当被视为extern "C" 时,指针引用的编组与指针指针相同。只是不要从 Python 传递 None,因为 C++ 会将其视为空引用。最好将函数声明为采用int**,这样您就可以处理None 可以从Python 传递的可能性。

用途:

func.argtypes = [POINTER(POINTER(c_int))]

调用它:

p = POINTER(c_int)()
func(byref(p))
print(p[:3])

【讨论】:

    猜你喜欢
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 2014-12-04
    • 1970-01-01
    • 2021-12-10
    • 2011-08-09
    相关资源
    最近更新 更多