4

I'm learning c++ (I've been learning for about 48 hours, so forgive the possible ignorance) for the purpose of speeding up some slow python code. I have written c++ function as follows;

std::tuple<float*, int*, int*, int**> scoreS(int**, float***, int**, float**, float**, float**, float**, float**, float**, float*, float**);

In my python file I do the following;

tmpScoreLib = cdll.LoadLibrary('/ScorerPT2.dll')
tmpScoreLib.ScoreSWrapped.argtypes = [POINTER(POINTER(c_int)), POINTER(POINTER(POINTER(c_float))), POINTER(POINTER(c_int)), POINTER(POINTER(c_float)), POINTER(POINTER(c_float)), POINTER(POINTER(c_float)), POINTER(POINTER(c_float)), POINTER(POINTER(c_float)), POINTER(POINTER(c_float)), POINTER(POINTER(c_float)), POINTER(POINTER(c_float))]

tmpvals1, tmpvals2, tmpvals3, tmpvals4 = tmpScoreLib.ScoreSWrapped(val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11)

I use ScoreSWrapped as a wrapper function around the ScoreS function as per this question.

However when I try and run this I get the following error:

ArgumentError: argument 1: <class 'TypeError'>: expected LP_LP_c_long instance instead of list

This is because val1 is a list of lists of floats rather than a pointer to a list of pointers to ints (I assume?) What I can't figure out is how to go from having a list of lists of ints in python to being able to pass the required int** to the c++ function. This is my first foray into this type of c++ wrapper so I could be doing multiple things wrong - assume total ignorance on my part! I have found other questions where they either user ctype.cast or ctypes.byref, but I can't really understand how to apply those.

user6916458
  • 400
  • 2
  • 7
  • 19
  • There are a bunch of things wrong here. First: Check [\[SO\]: How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) or [\[SO\]: How to create a Minimal, Reproducible Example (reprex (mcve))](https://stackoverflow.com/help/mcve) for more asking related details. Please create a minimal reproducible example. Then *CTypes* can't be used for ***C++*** types. And what's the 3 star pointers? – CristiFati Feb 02 '20 at 18:52
  • @CristiFati thanks for the input. I can't really add more code without making new code (the stuff within the function is long, convoluted and doesn't have any baring on the error. CTypes can't be used for c++ types? That's helpful, thanks. The 3 star pointers are 3D arrays, assuming I've set them up correctly(?). If there's a way I can improve the question, please let me know. – user6916458 Feb 02 '20 at 19:06

1 Answers1

1

You have to manually create the arrays to pass. ctypes supports this, of course, but you can’t just supply a Python list. For multidimensional arrays implemented as pointers to pointers, you’ll have to keep references around to every array at every level (to keep them alive) and copy their addresses into the “containing” array.

Finally, you can’t unpack a std::tuple using ctypes; you’ll have to make a custom structure type (or else return those values through yet more pointers). It might be easier to do the conversion in C than to work everything into a ctypes-compatible form.

Davis Herring
  • 36,443
  • 4
  • 48
  • 76