2012-05-07 30 views
2

これは、実際の有用な問題に取り組む前に私が取り組もうとしている簡単な例です。 Cコード:ポインタを渡して構造体を返すPythonのCtypes

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; 
} 

ザ・Pythonコード:

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 

出力:上記のコードは、私が期待どおりに動作します

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 

、私のポインタがに行くと修正とIれます私の整数を戻してください。この問題は、CでgeoTime構造体を作成してPythonに戻すときに発生します。 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; 

}

修正Pythonコード:

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 

私は、Cのコードのように私のコードを変更すると、代わりのmyTimeにナンセンスを取得しますPythonからの情報と戻り値は、testではなくnow_geoTimeに配置されます。何が間違っているかもしれないかに関するアイデア? Pythonのコードが何かにCコードが渡されます値で正しく動作しているようだので、私は期待する道をやっていないように見えます

出力の最後の例から:。

どれ
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 

アイデアは大いに感謝されます、私はこれを今かなり長い間働かせようとしています。前もって感謝します!

+1

私はあなたのコードにあなたが持っているのとまったく同じような渦を与えました。私はあなたが探している正しい出力を得ました。だから私が言うことは、あなたのコードが正しいと信じていることです。それはコンパイラまたはプラットフォームの問題かもしれません。 – JoeyG

+0

よろしくお願いいたします。少し掘り下げた後、コンパイルされたライブラリから何らかの理由で構造体を返すだけで動作しないことがわかりました。ここでは、いくつかのメソッドについては、構造体を返す必要があると仮定します.C側でヒープからいくつかのメモリをmallocし、構造体のコピーを持つポインタを返します。構造体を返すためのコンパイラオプションを調べて、そこに気づいているものがあるかどうかを調べることがあります。他の誰かが私にそれらに開いているいくつかのアイデアを持っている – Pat

答えて

1

私は64ビットのPython/64ビットのDLLに切り替えて、問題は解決しました。私がもう少しインスピレーションを感じている時、私はそれをコンパイラ、osまたはpythonに分離しようとするかもしれませんが、今はそれを実行します。