how to pass float* array to C method from python script whose memory allocation takes place in C lay

%3CLINGO-SUB%20id%3D%22lingo-sub-1770436%22%20slang%3D%22en-US%22%3Ehow%20to%20pass%20float*%20array%20to%20C%20method%20from%20python%20script%20whose%20memory%20allocation%20takes%20place%20in%20C%20lay%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1770436%22%20slang%3D%22en-US%22%3E%3CP%3EI%20am%20trying%20to%20call%20C%20methods%20from%26nbsp%3B%20python%20script%2C%20C%20method%20calls%20inturn%20the%20C%2B%2B%20method.%20I%20am%20allocating%20array%20inside%20the%20getResults()%20method%20using%20malloc().%20Now%20the%20issue%20is%20how%20to%20pass%20the%20arguments%20to%20float*%20oresults%20in%20python%20script%20whose%20memory%20allocation%20takes%20place%20inside%20the%20C%20layer.%20This%20is%20io.c%3C%2FP%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fbit.ly%2F30VrFbR%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fbit.ly%2F30VrFbR%3C%2FA%3E%3C%2FP%3E%3CPRE%3E%3CSPAN%20class%3D%22hljs-function%22%3E%3CSPAN%20class%3D%22hljs-keyword%22%3Eint%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22hljs-title%22%3EgetResults%3C%2FSPAN%3E%3CSPAN%20class%3D%22hljs-params%22%3E(%3CSPAN%20class%3D%22hljs-keyword%22%3Echar%3C%2FSPAN%3E*%20iFilename%2C%20%3CSPAN%20class%3D%22hljs-keyword%22%3Echar%3C%2FSPAN%3E*%20iStagename%2C%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eint%3C%2FSPAN%3E%20iStateidCnt%2C%20%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eint%3C%2FSPAN%3E*%20Stateids%2C%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eint%3C%2FSPAN%3E%20iEntityIdCount%2C%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eint%3C%2FSPAN%3E*%20iEntityids%2C%20%3CSPAN%20class%3D%22hljs-keyword%22%3Echar%3C%2FSPAN%3E*%20iEntityType%2C%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Echar%3C%2FSPAN%3E*%20iVariablegroup%2C%20%3CSPAN%20class%3D%22hljs-keyword%22%3Echar%3C%2FSPAN%3E*%20ivariable%2C%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eint%3C%2FSPAN%3E%20*oRescount%2C%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Efloat%3C%2FSPAN%3E*%20oResults)%3C%2FSPAN%3E%0A%3C%2FSPAN%3E%7B%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eint%3C%2FSPAN%3E%20Status%2C%20i%3B%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22hljs-function%22%3EEString%20%3CSPAN%20class%3D%22hljs-title%22%3Eetype%3C%2FSPAN%3E%3CSPAN%20class%3D%22hljs-params%22%3E(iEntityType)%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22hljs-title%22%3Estagename%3C%2FSPAN%3E%3CSPAN%20class%3D%22hljs-params%22%3E(iStagename)%3C%2FSPAN%3E%3C%2FSPAN%3E%3B%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-function%22%3EEString%20%3CSPAN%20class%3D%22hljs-title%22%3Evargroup%3C%2FSPAN%3E%3CSPAN%20class%3D%22hljs-params%22%3E(iVariablegroup)%3C%2FSPAN%3E%3C%2FSPAN%3E%3B%0A%20%20%20%20std%3A%3Avector%3CERF_INT%3E%20entity_ids%3B%0A%20%20%20%20std%3A%3Avector%3CERF_INT%3E%20stateids%3B%0A%20%20%20%20std%3A%3Avector%3CERF_FLOAT%3E%20results%3B%0A%20%20%20%20_CopyIntArrayIntoVector(iStateidCnt%2C%20Stateids%2C%20stateids)%3B%0A%20%20%20%20_CopyIntArrayIntoVector(iEntityIdCount%2C%20iEntityids%2C%20entity_ids)%3B%0A%20%20%20%20CreateIoInstance(iFilename%2C%20iStagename)%3B%0A%20%20%20%20ioData%20pIodata%20%3D%20CreateIoDataInstance()%3B%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eif%3C%2FSPAN%3E%20(iEntityIdCount%20%26lt%3B%3D%20%3CSPAN%20class%3D%22hljs-number%22%3E0%3C%2FSPAN%3E)%0A%20%20%20%20%20%20%20%20pIodata.setWholeSection(%3CSPAN%20class%3D%22hljs-keyword%22%3Etrue%3C%2FSPAN%3E)%3B%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eelse%3C%2FSPAN%3E%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20pIodata.setWholeSection(%3CSPAN%20class%3D%22hljs-keyword%22%3Efalse%3C%2FSPAN%3E)%3B%0A%20%20%20%20%20%20%20%20pIodata.setEntityList(entity_ids)%3B%0A%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20pIodata.setStateList(stateids)%3B%0A%20%20%20%20pIodata.setType(etype)%3B%0A%20%20%20%20pIodata.setVariableGroup(iVariablegroup)%3B%0A%20%20%20%20pIodata.setVariable(ivariable)%3B%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22hljs-comment%22%3E%2F%2FThis%20is%20C%2B%2B%20method%3C%2FSPAN%3E%0A%20%20%20%20Status%20%3D%20pIo-%26gt%3Bget_results(pIodata%2C%20results)%3B%0A%20%20%20%20*oRescount%20%3D%20results.size()%3B%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22hljs-comment%22%3E%2F%2Fallocation%20for%20oresults%20whose%20size%20%26gt%3B%202%3C%2FSPAN%3E%0A%20%20%20%20oResults%20%3D%20(%3CSPAN%20class%3D%22hljs-keyword%22%3Efloat%3C%2FSPAN%3E*)malloc(results.size()%20*%20sizeof(%3CSPAN%20class%3D%22hljs-keyword%22%3Efloat%3C%2FSPAN%3E))%3B%0A%20%20%20%20_CopyVectorIntoDoubleArray(results%2C%20oResults)%3B%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Ereturn%3C%2FSPAN%3E%20Status%3B%0A%7D%0A%0A%3C%2FERF_FLOAT%3E%3C%2FERF_INT%3E%3C%2FERF_INT%3E%3C%2FPRE%3E%3CP%3Etest.py%3C%2FP%3E%3CPRE%3E%3CSPAN%20class%3D%22hljs-keyword%22%3Efrom%3C%2FSPAN%3E%20ctypes%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eimport%3C%2FSPAN%3E%20*%0A%3CSPAN%20class%3D%22hljs-keyword%22%3Eimport%3C%2FSPAN%3E%20os%2C%20sys%0Adll%20%3D%20CDLL(%3CSPAN%20class%3D%22hljs-string%22%3E'D%3A%5C%5Cerf_utils_python%5C%5Cerf_utils_io.dll'%3C%2FSPAN%3E)%0Adll.getresults.argtypes%20%3D%20(c_char_p%2Cc_char_p%2Cc_int%2CPOINTER(c_int)%2Cc_int%2CPOINTER(c_int)%2Cc_char_p%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20c_char_p%2Cc_char_p%2CPOINTER(c_int)%2CPOINTER(c_float))%0Adll.getresults.restype%20%3D%20c_int%0A%0A%0A%3CSPAN%20class%3D%22hljs-function%22%3E%3CSPAN%20class%3D%22hljs-keyword%22%3Edef%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22hljs-title%22%3Emake_array%3C%2FSPAN%3E(%3CSPAN%20class%3D%22hljs-params%22%3Ectype%2Carr%3C%2FSPAN%3E%3A(%3C%2Fimg%3E%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Ereturn%3C%2FSPAN%3E%20len(arr)%2C(ctype%20*%20len(arr))(*arr)%0A%0A%3CSPAN%20class%3D%22hljs-function%22%3E%3CSPAN%20class%3D%22hljs-keyword%22%3Edef%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22hljs-title%22%3Egetresults%3C%2FSPAN%3E(%3CSPAN%20class%3D%22hljs-params%22%3Efilename%2Cstagename%2Csids%2Ceids%2Centitytype%2Cgroups%2Cvariables%3C%2FSPAN%3E%3A(%3C%2Fimg%3E%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eif%3C%2FSPAN%3E(len(sids)%26gt%3B%3CSPAN%20class%3D%22hljs-number%22%3E0%3C%2FSPAN%3E)%3A%0A%20%20%20%20%20%20%20stateidcount%2Cstateids%20%3D%20make_array(c_int%2Csids)%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Eif%3C%2FSPAN%3E(len(eids)%26gt%3B%3CSPAN%20class%3D%22hljs-number%22%3E0%3C%2FSPAN%3E)%3A%0A%20%20%20%20%20%20%20entityidcount%2Centityid%20%3D%20make_array(c_int%2Ceids)%0A%20%20%20%20oresultlen%20%3D%20c_int()%0A%20%20%20%20float_values%20%3D%20POINTER(c_float)%0A%20%20%20%20err%20%3D%20dll.getresults(filename%2Cstagename%2Cstateidcount%2Cstateids%2Centityidcount%2Centityid%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entitytype%2Cgroups%2Cvariables%2Cbyref(oresultlen)%2C%20byref(float_values))%0A%20%20%20%20%3CSPAN%20class%3D%22hljs-keyword%22%3Ereturn%3C%2FSPAN%3E%20err%2Coresultlen.value%2C%20float_values%0A%0Afilename%20%3D%20%3CSPAN%20class%3D%22hljs-string%22%3Eb'D%3A%5C%5Cinputfile.h5'%3C%2FSPAN%3E%0Astagename%20%3D%20%3CSPAN%20class%3D%22hljs-string%22%3Eb%22post%22%3C%2FSPAN%3E%0Astateids%20%3D%20%5B%3CSPAN%20class%3D%22hljs-number%22%3E2%3C%2FSPAN%3E%5D%0Astateidcount%20%3D%20%3CSPAN%20class%3D%22hljs-number%22%3E1%3C%2FSPAN%3E%0Aentityidcount%20%3D%20%3CSPAN%20class%3D%22hljs-number%22%3E1%3C%2FSPAN%3E%0Aentityid%20%3D%20%5B%3CSPAN%20class%3D%22hljs-number%22%3E1%3C%2FSPAN%3E%5D%0Aentitytype%20%3D%20%3CSPAN%20class%3D%22hljs-string%22%3Eb%22test%22%3C%2FSPAN%3E%0Avariablecount%20%3D%20%3CSPAN%20class%3D%22hljs-number%22%3E1%3C%2FSPAN%3E%0Avariablegroup%20%3D%20%3CSPAN%20class%3D%22hljs-string%22%3Eb%22testdata%22%3C%2FSPAN%3E%0Avariable%20%3D%20%3CSPAN%20class%3D%22hljs-string%22%3Eb%22next%22%3C%2FSPAN%3E%0A%0Aerr%2Coreslen%2Cores%20%3D%20getresults(filename%2Cstagename%2Cstateids%2Centityid%2Centitytype%2Cvariablegroup%2Cvariable)%0A%0A%3C%2FPRE%3E%3CBLOCKQUOTE%3E%3CP%3ETypeError%3A%20byref()%20argument%20must%20be%20a%20ctypes%20instance%2C%20not%20'_ctypes.PyCPointerType'%20this%20is%20the%20error%20I%20get%20when%20I%20run%20the%20script.%20I%20am%20little%20confused%20on%20how%20to%20send%20argument%20for%20float%20*oresults%20in%20script.%3C%2FP%3E%3C%2FBLOCKQUOTE%3E%3C%2FLINGO-BODY%3E
Regular Visitor

I am trying to call C methods from  python script, C method calls inturn the C++ method. I am allocating array inside the getResults() method using malloc(). Now the issue is how to pass the arguments to float* oresults in python script whose memory allocation takes place inside the C layer. This is io.c

https://bit.ly/30VrFbR

int getResults(char* iFilename, char* iStagename, int iStateidCnt, 
    int* Stateids, int iEntityIdCount, int* iEntityids, char* iEntityType,
    char* iVariablegroup, char* ivariable, int *oRescount,
    float* oResults)
{
    int Status, i;
        EString etype(iEntityType), stagename(iStagename);
    EString vargroup(iVariablegroup);
    std::vector<ERF_INT> entity_ids;
    std::vector<ERF_INT> stateids;
    std::vector<ERF_FLOAT> results;
    _CopyIntArrayIntoVector(iStateidCnt, Stateids, stateids);
    _CopyIntArrayIntoVector(iEntityIdCount, iEntityids, entity_ids);
    CreateIoInstance(iFilename, iStagename);
    ioData pIodata = CreateIoDataInstance();
    if (iEntityIdCount <= 0)
        pIodata.setWholeSection(true);
    else
    {
        pIodata.setWholeSection(false);
        pIodata.setEntityList(entity_ids);
    }
        
    pIodata.setStateList(stateids);
    pIodata.setType(etype);
    pIodata.setVariableGroup(iVariablegroup);
    pIodata.setVariable(ivariable);
        //This is C++ method
    Status = pIo->get_results(pIodata, results);
    *oRescount = results.size();
        //allocation for oresults whose size > 2
    oResults = (float*)malloc(results.size() * sizeof(float));
    _CopyVectorIntoDoubleArray(results, oResults);
    return Status;
}

test.py

from ctypes import *
import os, sys
dll = CDLL('D:\\erf_utils_python\\erf_utils_io.dll')
dll.getresults.argtypes = (c_char_p,c_char_p,c_int,POINTER(c_int),c_int,POINTER(c_int),c_char_p,
                                  c_char_p,c_char_p,POINTER(c_int),POINTER(c_float))
dll.getresults.restype = c_int


def make_array(ctype,arr):
    return len(arr),(ctype * len(arr))(*arr)

def getresults(filename,stagename,sids,eids,entitytype,groups,variables):
    if(len(sids)>0):
       stateidcount,stateids = make_array(c_int,sids)
    if(len(eids)>0):
       entityidcount,entityid = make_array(c_int,eids)
    oresultlen = c_int()
    float_values = POINTER(c_float)
    err = dll.getresults(filename,stagename,stateidcount,stateids,entityidcount,entityid,
                                entitytype,groups,variables,byref(oresultlen), byref(float_values))
    return err,oresultlen.value, float_values

filename = b'D:\\inputfile.h5'
stagename = b"post"
stateids = [2]
stateidcount = 1
entityidcount = 1
entityid = [1]
entitytype = b"test"
variablecount = 1
variablegroup = b"testdata"
variable = b"next"

err,oreslen,ores = getresults(filename,stagename,stateids,entityid,entitytype,variablegroup,variable)

TypeError: byref() argument must be a ctypes instance, not '_ctypes.PyCPointerType' this is the error I get when I run the script. I am little confused on how to send argument for float *oresults in script.

0 Replies