3

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!

Pat
  • 41
  • 3
  • 1
    I gave your code a whirl, exactly as you have it. I got the correct output that you are looking for. So all I can say is that I believe your code is correct; it may be a compiler or a platform issue. – JoeyG May 07 '12 at 18:17
  • Okay, thanks. After a bit of digging I found that for some reason returning structs from my compiled library just doesn't work. For now I'll go with the assumption that for the few methods I need that return a struct I'll wrap it on the C side to malloc some memory from the heap and return a pointer with a copy of the struct. I might try looking into the compiler options for returning structs and see if there's anything I notice in there. If anyone else has some ideas I'm open to them – Pat May 07 '12 at 19:22

1 Answers1

1

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.

Pat
  • 41
  • 3