This is a simple example of something I'm trying to get working before tackling an actual useful problem. The C code:
typedef struct {
uint32_t seconds;
uint32_t nanoseconds;
} geoTime;
int myTest(geoTime *myTime){
printf("Time: %d %d\n", myTime->seconds, myTime->nanoseconds);
myTime->seconds = myTime->nanoseconds;
geoTime T = {314, 159};
printf("MyTime: %d %d retValue: %d %d\n", myTime->seconds, myTime->nanoseconds, T.seconds, T.nanoseconds);
return 314;
}
The Python code:
import ctypes
import time
import math
lib_astro = ctypes.CDLL("libastroC.so")
class geoTime(ctypes.Structure):
_fields_ = [("seconds", ctypes.c_uint),
("nanoseconds", ctypes.c_uint)]
now = time.time()
print "Python Now: ", now
now_geoTime = geoTime()
now_geoTime.seconds = ctypes.c_uint(int((math.floor(now))))
now_geoTime.nanoseconds = ctypes.c_uint(int(math.floor(math.modf(now)[0] * 1000000000)))
print "Python geoTime now:", now_geoTime.seconds, now_geoTime.nanoseconds
lib_astro.myTest.argtypes = [ctypes.POINTER(geoTime)]
lib_astro.myTest.restype = geoTime
print "************* ENTERING C ********************"
test = lib_astro.myTest(ctypes.byref(now_geoTime))
print "************* EXITING C **********************"
print "Modified now_geoTime: ",now_geoTime.seconds, now_geoTime.nanoseconds
print "test: ",test
Output:
Python Now: 1336401085.43
Python geoTime now: 1336401085 432585000
************* ENTERING C ********************
Time: 1336401085 432585000
MyTime: 432585000 432585000 retValue: 314 159
************* EXITING C **********************
Modified now_geoTime: 432585000 432585000
test: 314
The above code works exactly as I would expect, my pointer goes in and is modified and I get my integer back. The problem happens when I try to create a geoTime structure in C and return that back to Python.
Added/modified code in C:
geoTime patTest(geoTime *myTime){
printf("Time: %d %d\n", myTime->seconds, myTime->nanoseconds);
myTime->seconds = myTime->nanoseconds;
geoTime T = {314, 159};
printf("MyTime: %d %d retValue: %d %d\n", myTime->seconds, myTime->nanoseconds, T.seconds, T.nanoseconds);
return T;
}
Modified Python code:
lib_astro.patTest.argtypes = [ctypes.POINTER(geoTime)]
lib_astro.patTest.restype = geoTime
print "************* ENTERING C ********************"
test = lib_astro.patTest(ctypes.byref(now_geoTime))
print "************* EXITING C **********************"
print "Modified now_geoTime: ",now_geoTime.seconds, now_geoTime.nanoseconds
print "Type of test: ",test
print "Information in test: ", test.seconds, test.nanoseconds
Once I change my code like that the C code gets nonsense into myTime instead of the information from Python and the return value gets placed into now_geoTime instead of test. Any ideas on what might be going wrong? It looks like the python code isn't doing something the way I expect because the C code seems to be working correctly with the values that get passed in.
Output from the last example:
Python Now: 1336404920.77
Python geoTime now: 1336404920 773674011
************* ENTERING C ********************
Time: 90500 -17037640
MyTime: -17037640 -17037640 retValue: 314 159
************* EXITING C **********************
Modified now_geoTime: 314 159
Type of test: <__main__.geoTime object at 0x82bedf4>
Information in test: 137096800 134497384
Any ideas would be greatly appreciated, I've been trying to get this to work for quite a while now. Thanks in advance!
I switched to 64 bit python/64 bit dlls and the problem went away. When I'm feeling a little more inspired I might try to isolate it down to the compiler, the os or python but for now I'm going to run with it.
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