Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python passing user-defined class by reference to DLLs

I am currently working on a project that requires to access functions in DLLs, and I found ctypes to handle the function call for me. However, I encounter some difficulties when some functions ask to pass parameters by reference. I've tried the ctypes.by_ref() but it doesn't work because the object is a user-defined class.

And then I gave ctypes.pointer() a try and it spits out the error message: "type must have storage info". I guess that means it only takes ctypes data types?

My code:

from ctypes import *
class myclass():
    a= None # requiring c_int32
    b= None # requiring c_int32
myci= myclass()
myci.a= c_int32(255)
myci.b= c_int32(0)
mycip= pointer(myci)  # let's say it's Line 8 here
loadso= cdll.LoadLibrary(mydll)
Result= loadso.thefunction (mycip) # int thefunction(ref myclass)

And the terminal output:

Line 8: TypeError: _type_ must have storage info

I would like to know 1) what does that error message mean? and 2) the way to work around and pass a user-defined class by reference to an external DLL.

Thank you in advance for your time.

like image 409
nakamurayuristeph Avatar asked Aug 09 '26 18:08

nakamurayuristeph


1 Answers

The error message means that you can't create a ctypes pointer to a non-ctypes type. ctypes types have the information needed to marshal values correctly to C.

Read ctypes: Structures and Unions. The first sentence is (emphasis mine):

Structures and unions must derive from the Structure and Union base classes which are defined in the ctypes module.

For example:

>>> from ctypes import *
>>> class Test(Structure):
...   _fields_ = [('a',c_int32),
...               ('b',c_int16),
...               ('c',c_int16)]
...
>>> t = Test(1,2,3)
>>> pointer(t)
<__main__.LP_Test object at 0x00000234A8750A48>
>>> bytes(t)
b'\x01\x00\x00\x00\x02\x00\x03\x00'

Note that a pointer can be taken and that the raw bytes of the structure can be displayed. The structure is little-endian and there are four bytes allocated for the c_int32, and two bytes each for the two c_int16 members.

like image 171
Mark Tolonen Avatar answered Aug 11 '26 09:08

Mark Tolonen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!