I built a cgo library and used python (with ctypes package) to call it. The code was compiled into both 32 bit and 64 bit versions and these libraries were called by 32 bit and 64 bit python programs respectively. I found out obviously the parameters were not passed properly. I think probably it is related to how the array is defined and passed between the python programs and the libraries.
For example, a function in go library "callnames.so" is defined as
func Initialize(namelist []*C.char, grp *C.char)
and the part of python code calling this function is class GoSliceChar(Structure): fields = [("data", POINTER(c_char_p)), ("len", c_longlong), ("cap", c_longlong)]
numNames = 3
n1 = c_char_p(b"peter")
n2 = c_char_p(b"tom")
n3 = c_char_p(b"nancy")
group = c_char_p(b"group1")
names = GoSliceChar((c_char_p * numComponents)(n1, n2, n3), numNames, numNames )
lib = cdll.LoadLibrary("./callnames.so")
lib.Initialize(names, group)
These code works just fine under 64 bit environment, that is, python-64 + 64 bit cgo library. However, the problem occurred when I switched to 32 bit. I had a quick and dirty fix by changing the definition of GoSliceChar in python to
class GoSliceChar(Structure):
_fields_ = [("data", POINTER(c_char_p)), ("len", c_long), ("cap", c_long)]
But I dont really understand why the problem was solved and whether it is a solid solution. Please help. Thanks.
I had some new finding on my problem. Looks like after compilation of the cgo library, an .h file is AUTOMATICALLY generated. In this file, all the arrays are defined as GoSlice
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
For a 32 bit library, GoInt is defined by
typedef GoInt32 GoInt;
whereas for a 64 bit library, GoInt is defined by
typedef GoInt32 GoInt;
It looks to me, one has to ensure the python code to accommodate this while calling these libraries
class GoSliceChar(Structure):
if is_64bit():
_fields_ = [("data", POINTER(c_char_p)), ("len", c_longlong), ("cap", c_longlong)]
else:
_fields_ = [("data", POINTER(c_char_p)), ("len", c_long), ("cap", c_long)]