Passing Array of Objects OR Array of Arrays Between Python & C++ Library -


i've extern "c" declaration of c++ function, compiled part of shared library on ubuntu, getvphistory

void getvphistory(actorpos allpostions[], uint numact, uint numdim, uint numstate) { uint actordimpaircount = numact * numdim; uint actordimpairindex = 0; float val = 1.0; (uint actor = 0; actor < numact; ++actor) {   (uint dim = 0; dim < numdim; ++dim) {     actorpos *ap = &allpostions[actordimpairindex];     ++actordimpairindex;     ap->actor = actor;     ap->dim = dim;     ap->nstate = numstate;     (uint state = 0; state < numstate; ++state) {       ap->pos[state] = val;       val += 0.5; // incrementing testing     }   } } 

}

the actorpos object defined as:

using actorpos = struct singleactorpositions {   unsigned int actor;   unsigned int dim;   unsigned int nstate;   float pos[1000]; // possible upper limit of nstate 

};

i'm using ctypes in python try use function, following code:

import ctypes c  actorcnt = 2 dimensioncnt = 2; statecnt = 2  smplib = c.cdll.loadlibrary('libsmpdyn.so') class poshist(c.structure):     _fields_ = [("actorid",c.c_uint),\     ("dimensionid",c.c_uint),\     ("statecnt",c.c_uint),\     ('positions',c.c_float*statecnt)] poshistarrtype = poshist*(actorcnt*dimensioncnt)  poshists = poshistarrtype()  proto_ps = c.cfunctype(c.c_voidp,c.pointer(poshistarrtype),c.c_uint,c.c_uint,c.c_uint) getvphistory = proto_ps(('getvphistory',smplib))  getvphistory(poshists,actorcnt,dimensioncnt,statecnt) 

this runs no errors, when try access returned data inside poshists, see first object has been filled. running this:

for p in poshists:   print('actor: %d, dimension: %d'%(p.actorid,p.dimensionid))   o in p.positions:     print('\t%0.2f'%o) 

gives me this:

actor: 0, dimension: 0     1.00     1.50 actor: 0, dimension: 0     0.00     0.00 actor: 0, dimension: 0     0.00     0.00 actor: 0, dimension: 0     0.00     0.00 

i.e., after first poshist object in array, others still show initial values. can confirm getvphistory function filling out array, seems me issue of full array not getting passed poshists variable. please!

edit

suspecting struct part of issue - , more needed problem - i've simplified use 3-d array. c getvphistory function now:

  void getvphistory(float hist[100][100][100], uint numact, uint numdim, uint numstate)   {     // talk little     cout << "actors: " << numact << "dimensions: " << numdim << "states: " << numstate << endl;      // loop through actors, dims, , states , store positions     float val = 1.0;     (uint actor = 0; actor < numact; ++actor)     {       //cout << "actor " << actor << endl;       (uint dim = 0; dim < numdim; ++dim)       {         //cout << "dimension " << dim << endl;         (uint state = 0; state < numstate; ++state)         {           hist[actor][dim][state] = val;           cout << "a: " << actor << " d: " << dim << " s: " << state << "\tadded position: " << val << endl;           val += 0.5;         }       }     }          } 

and python code now:

actorcnt = 3; dimensioncnt = 2; statecnt = 5 poshisttype = ((c.c_float * statecnt) * dimensioncnt)*actorcnt  proto_ps = c.cfunctype(c.c_voidp,c.pointer(poshisttype),c.c_uint,c.c_uint,c.c_uint) getvphistory = proto_ps(('getvphistory',smplib))  poshists = poshisttype() getvphistory(poshists,actorcnt,dimensioncnt,statecnt)  in range(actorcnt):   d in range(dimensioncnt):     print('pos hist actor %d, dimension %d:'%(a,d))     print('\t[%s]'%', '.join(['%0.2f'%p p in poshists[a][d]])) 

so i'm passing pointer memory 3-d array, data filled in in c, , read data in python. console output c verifies data being stored:

actors: 3 dimensions: 2 states: 5 a: 0 d: 0 s: 0  added position: 1 a: 0 d: 0 s: 1  added position: 1.5 a: 0 d: 0 s: 2  added position: 2 a: 0 d: 0 s: 3  added position: 2.5 ... a: 2 d: 1 s: 2  added position: 14.5 a: 2 d: 1 s: 3  added position: 15 a: 2 d: 1 s: 4  added position: 15.5 

yet, without complication of struct, have same issue of first inner-most array coming data:

pos hist actor 0, dimension 0:     [1.00, 1.50, 2.00, 2.50, 3.00] pos hist actor 0, dimension 1:     [0.00, 0.00, 0.00, 0.00, 0.00] pos hist actor 1, dimension 0:     [0.00, 0.00, 0.00, 0.00, 0.00] pos hist actor 1, dimension 1:     [0.00, 0.00, 0.00, 0.00, 0.00] pos hist actor 2, dimension 0:     [0.00, 0.00, 0.00, 0.00, 0.00] pos hist actor 2, dimension 1:     [0.00, 0.00, 0.00, 0.00, 0.00] 

if hard code array in c function definition hist[3][2][5] - same it's created in python - same behavior occurs.

you have declare structure same dimensions betweeen c++ , python:

working (windows) c++ dll:

typedef unsigned int uint;  struct actorpos {     unsigned int actor;     unsigned int dim;     unsigned int nstate;     float pos[1000]; // possible upper limit of nstate };  extern "c" __declspec(dllexport) void getvphistory(actorpos allpostions[], uint numact, uint numdim, uint numstate) {     uint actordimpairindex = 0;     float val = 1.0;     for(uint actor = 0; actor < numact; ++actor)     {         for(uint dim = 0; dim < numdim; ++dim)         {             actorpos* ap = &allpostions[actordimpairindex];             ++actordimpairindex;             ap->actor = actor;             ap->dim = dim;             ap->nstate = numstate;             for(uint state = 0; state < numstate; ++state)             {                 ap->pos[state] = val;                 val += 0.5; // incrementing testing             }         }     } } 

python code:

import ctypes c  actorcnt = 2; dimensioncnt = 2; statecnt = 2  smplib = c.cdll('test') class poshist(c.structure):     _fields_ = [("actorid",c.c_uint),\     ("dimensionid",c.c_uint),\     ("statecnt",c.c_uint),\     ('positions',c.c_float*1000)] # declare same size struct in c++ poshistarrtype = poshist*(actorcnt*dimensioncnt)  poshists = poshistarrtype()  proto_ps = c.cfunctype(c.c_voidp,c.pointer(poshistarrtype),c.c_uint,c.c_uint,c.c_uint) getvphistory = proto_ps(('getvphistory',smplib))  getvphistory(poshists,actorcnt,dimensioncnt,statecnt)  p in poshists:     print('actor: %d, dimension: %d'%(p.actorid,p.dimensionid))      # here, iterate number of states returned...     in range(p.statecnt):         print('\t%0.2f'%p.positions[i]) 

output:

actor: 0, dimension: 0     1.00     1.50 actor: 0, dimension: 1     2.00     2.50 actor: 1, dimension: 0     3.00     3.50 actor: 1, dimension: 1     4.00     4.50 

Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -