Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从struct的C数组到带有ctypes的NumPy数组的高效转换 下面我尝试使用C++ DLL,使用 Cython ,教程适合我的情况,但我从来没有使用过,代码> cType 。由于频繁的SO浏览,我现在使用ctypes成功地调用了我在DLL中感兴趣的函数。我现在面临的问题是如何使用Python中结构数组的结果_Python_C++_C_Numpy_Ctypes - Fatal编程技术网

从struct的C数组到带有ctypes的NumPy数组的高效转换 下面我尝试使用C++ DLL,使用 Cython ,教程适合我的情况,但我从来没有使用过,代码> cType 。由于频繁的SO浏览,我现在使用ctypes成功地调用了我在DLL中感兴趣的函数。我现在面临的问题是如何使用Python中结构数组的结果

从struct的C数组到带有ctypes的NumPy数组的高效转换 下面我尝试使用C++ DLL,使用 Cython ,教程适合我的情况,但我从来没有使用过,代码> cType 。由于频繁的SO浏览,我现在使用ctypes成功地调用了我在DLL中感兴趣的函数。我现在面临的问题是如何使用Python中结构数组的结果,python,c++,c,numpy,ctypes,Python,C++,C,Numpy,Ctypes,此C函数如下所示: void myfun( double a, //...more double parameters int max_iter, int * nb_iter, myStruct * res_arr, bool *

此C函数如下所示:

void myfun(
                 double         a,
                 //...more double parameters
                 int            max_iter,
                 int *          nb_iter,
                 myStruct *     res_arr,
                 bool *         ok
                );
typedef struct  {
             double dat;

             int    k;
             int    m;
            // ... more int

             double b;
             double v;
             //...more double

            } myStruct;
myStruct
定义如下:

void myfun(
                 double         a,
                 //...more double parameters
                 int            max_iter,
                 int *          nb_iter,
                 myStruct *     res_arr,
                 bool *         ok
                );
typedef struct  {
             double dat;

             int    k;
             int    m;
            // ... more int

             double b;
             double v;
             //...more double

            } myStruct;
我通过以下Python代码调用此函数:

import ctypes
lib = ctypes.CDLL('PATH_TO_DLL\\lib.dll')

myFunPy = getattr(lib,"?myFun@@YANNNNN_BUNCH_OF_Ns_NNNHPEAHPEAUmyStruct@@PEA_N@Z") # name found through dumpbin.exe (due to C++)

class myStruct(ctypes.Structure):
    _fields_ = [("k", ctypes.c_int),
                ("m", ctypes.c_int),
                #...more int parameters

                ("b", ctypes.c_double),
                ("v", ctypes.c_double)
                #...more double parameters
               ]

myFunPy.argtypes = [ctypes.c_double,
                   // ... more double parameters

                   ctypes.c_int,
                   ctypes.POINTER(ctypes.c_int),
                   ctypes.POINTER(myStruct),
                   ctypes.POINTER(ctypes.c_bool)]

myFunPy.restype = ctypes.c_void_p

max_iter = 10000
a = ctypes.c_double(0.1)
// ... more double parameters definitions

nb_iter = ctypes.c_int(0) # value doesn't matter, it is initialized in myFun
ok = ctypes.c_bool(True)

res_arr = (myStruct * max_iter)()

myFunPy(a, ..., max_iter, ctypes.byref(nb_iter), res_arr, ctypes.byref(ok))
现在
myFun
修改了
res\u arr
,这是一个结构数组,可以从上面的代码中看到。 确实如此

<__main__.myStruct_Array_10000 at 0x97966c8>)
在上面显示的代码之后,但我无法理解如何将其转换为NumPy数组以供将来高效使用

当然,我可以使用
for field、u-in-struct.\u fields\uu
之类的东西来处理循环,如图所示,但这不是重点,因为我使用DLL来加快计算速度(我确实看到了执行时间的差异)
res_arr
的范围从200KB到1MB,有上万行和几十列,因此我确信有一种方法可以避免使用循环遍历所有内容,但我不知道如何做到这一点


看起来,如果不是一个struct数组,就更容易了。有(还有、、和)接近这个主题,但它要么只是转换一个结构、一个数组,要么是转换一些接近但与我不完全一样的东西,我没有成功地适应这些解决方案,所以也许有一种方法可以基于此来回答,但无论如何,我洗耳恭听。

我们有几乎相同的问题,但在我的情况下,我使用的是CUDA DLL,所以我的编译器是
nvcc
。但是我相信这也可以通过普通的
g++
编译器来完成。在任何情况下,以下是我将结构数组从我的CPP文件转换为可用的Python列表/数组所做的步骤。我不会再看你的密码了;相反,我只给你举一个例子,可以在这里找到:

但重要步骤总结如下:

void myfun(
                 double         a,
                 //...more double parameters
                 int            max_iter,
                 int *          nb_iter,
                 myStruct *     res_arr,
                 bool *         ok
                );
typedef struct  {
             double dat;

             int    k;
             int    m;
            // ... more int

             double b;
             double v;
             //...more double

            } myStruct;
  • 使用包含函数的
    extern“C”
    声明的必要头文件创建.cpp文件。在.cpp文件中,我返回了一个struct数组,而不是返回一个
    void

  • 使用编译器创建.dll文件。同样,在我的例子中,它是
    nvcc
    。我通过github帐户链接的示例代码是使用
    nvcc
    编译的

  • 在.py文件中:

    3.1使用
    ctypes.Structure
    创建一个Python类,以便在.cpp/.h文件中复制结构定义

    3.2使用
    argtype/restype
    初始化输入/输出。由于my.cpp函数返回一个struct数组,因此
    restype
    ctypes.Pointer()给出

    3.3我将所有输入转换为可读的CType。在my.py文件中调用函数后,可以使用(
    results=\u results[:array\u SIZE]
    )将生成的结构数组(
    \u results
    )转换为Python列表


  • 我希望这有帮助

    它确实有效,谢谢!实际上,我已经重写了我的C代码来使用Double数组,而忘记了Struct,因为在我的例子中,它可以很容易地完成(我只是在其中有Double和Int)。我还意识到,如果我想轻松使用阵列,就必须对其进行输出。这是最好的解决方案!