python传递struct和指向c函数的指针用于输入和输出

时间:2016-08-25 06:08:10

标签: python c++ c ctypes

我做如下,但得到错误。

使用ctypes有什么问题,或者我传递的参数类型有什么问题吗?

我认为应该考虑以下三点:

  1. 生成在python中传递给c函数的正确参数。

  2. 将带有struct类型的指针传递给c函数。

  3. 如果在python代码中需要struct,则右实例化struct依赖于给定的数组。

  4. 我是c的新手,特别是指针。

    c code:struct,ansfer.h

       (function(){
                     var str ="";
                     var new_timestamp =  parseInt($("#current_time").data("timestamp"))+1000;
                     var date = new Date(new_timestamp);
                    for( var a = 0; a < 24 ; a++)
                    {
                        if( a== date.getHours() )
                        {
                            str +="<option selected>"+(a<10?("0"+a):a)+"</option>" ;
                        }
                        else
                        {
                           str +="<option>"+(a<10?("0"+a):a)+"</option>" ; 
                        }
    
                    }
    
                    $("#bank-order-time  [name=\"hour\"]").html(str);
    
                     var mins = "";
    
                    for( var b = 0; b < 60; b++)
                    {
                        if( b == date.getMinutes())
                        {
                            mins +="<option selected>"+(b<10?("0"+b):b)+"</option>" ;
                        }
                        else
                        {
                           mins +="<option>"+(b<10?("0"+b):b)+"</option>" ; 
                        }
    
                    }
                    $("#bank-order-time  [name=\"minutes\"]").html(mins);
    
                })();
    

    python,ansfer.c

    调用的函数
    typedef unsigned char boolean_T;
    
    
    struct emxArray_real_T
    {
    
    
        double *data;
        int *size;
        int allocatedSize;
        int numDimensions;
        boolean_T canFreeData;
    };
    

    然后,void ansferA(const emxArray_real_T *dataArray, double H, emxArray_real_T *TE, emxArray_real_T *Lag) { ... P2 += dataArray->data[a + dataArray->size[0] * b]; ... TE->data[a + TE->size[0] * b] = te; Lag->data[a + Lag->size[0] * b] = h; ... }

    生成了libansfer.so。

    我根据建议改写了test.py.添加结构如下。

    python代码:test.py

    gcc -o libansfer.so -shared -fPIC *.c

    但类似的错误

    import numpy as np
    import ctypes
    
    c_double_p = ctypes.POINTER(ctypes.c_double)
    c_int_p = ctypes.POINTER(ctypes.c_int)
    
    class emxArray_real_T(ctypes.Structure):
        _fields_ = [
            ("data",          c_double_p),  
            ("size",          c_int_p), 
            ("allocatedSize", ctypes.c_int),
            ("numDimensions", ctypes.c_int),
            ("canFreeData",   ctypes.c_bool)
        ]
    
    indata = np.array([[1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1],[2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2],[3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,2.2,2.2,2.2]])
    
    LL, CC = indata.shape 
    
    TE = np.zeros((LL,LL), dtype=np.double)
    Lag = np.zeros((LL,LL), dtype=np.double)
    
    SS = np.array([LL, CC])
    instruct = emxArray_real_T()
    instruct.data = c_double_p(ctypes.c_double(indata.ctypes.data))
    instruct.size = c_int_p(ctypes.c_int(SS.ctypes.data))
    instruct.allocatedSize = ctypes.c_int(LL*CC)
    instruct.numDimensions = ctypes.c_int(2)
    instruct.canFreeData = ctypes.c_bool(0)
    
    ss = np.array([LL, LL])
    outstruct1 = emxArray_real_T()
    outstruct1.data = c_double_p(ctypes.c_double(TE.ctypes.data))
    outstruct1.size = c_int_p(ctypes.c_int(ss.ctypes.data))
    outstruct1.allocatedSize = ctypes.c_int(LL*LL)
    outstruct1.numDimensions = ctypes.c_int(2)
    outstruct1.canFreeData = ctypes.c_bool(0)
    
    outstruct2 = emxArray_real_T()
    outstruct2.data = c_double_p(ctypes.c_double(Lag.ctypes.data))
    outstruct2.size = c_int_p(ctypes.c_int(ss.ctypes.data))
    outstruct2.allocatedSize = ctypes.c_int(LL*LL)
    outstruct2.numDimensions = ctypes.c_int(2)
    outstruct2.canFreeData = ctypes.c_bool(0)
    
    lib = ctypes.cdll.LoadLibrary('./libansfer.so')
    
    lib.ansferA(instruct,ctypes.c_double(3), outstruct1, outstruct2)
    

1 个答案:

答案 0 :(得分:0)

这不是答案,但格式规则不允许我将其作为评论(并且仍然可读)。

结构将如下所示:

c_double_p = ctypes.POINTER(ctypes.c_double)
c_int_p = ctypes.POINTER(ctypes.c_int)

class emxArray_real_T(ctypes.Structure):
    _fields_ = [
        ("data",          c_double_p),  
        ("size",          c_int_p), 
        ("allocatedSize", ctypes.c_int),
        ("numDimensions", ctypes.c_int),
        ("canFreeData",   ctypes.c_bool)
    ]

我必须猜测canFreeData的类型,boolean_T不是标准的C类型。

然后用以下内容初始化结构:

emxArray_struct = emxArray_real_T( insert values here as parameters )

我没有使用numpy,所以我不知道它的类型是否/如何映射到ctypes或常规的python变量类型。