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.
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
ctypesmodule.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With