2017-04-17 17 views
1

dtllをpythonにctypesで統合すると、dllはコールバック関数を設定する必要があります。 、あなたの可能性エラー:しかし、DLLコールバック関数は、私は、以下のようにそれを試してpython ctypes、コールバック関数の補数型はC++リファレンス

void setCallBack(void(*)(Data &a)) 

Data is C struct, declare as below 
typedef struct { 
    int index, 
    .... 
}Data 

の下に、私はctypesのことで、それを設定する方法が明確でないと宣言したが、「[エラー-1073741795] Windowsエラー0xC000001D WindowsError」を返しますコールバックを設定する方法の例を挙げてください。

mydll = cdll.LoadLibrary("XXX.dll") 
callback_type = CFUNCTYPE(None, POINTER(Data)) 
callback = callback_type(Data) 
mydll.setCallBack(callback) 

def dataResponse(data): 
    print data.index 

class Data(ctypes.Structure): 
    _fields_ = [("index", c_int)] 

答えて

0

あなたの構造が正しいように見えますが、あなたは、WindowsのAPIに呼び出している場合は、あなたの呼び出し規約は、(あなたがCDECLを使用しているが、これはWindows API呼び出しであれば、あなたはSTDCALLが必要)オフ可能性があります。

あなたはまた、代わりにCDECLのSTDCALLを使用するコールバック関数を提供する必要がありmydll = WinDLL("XXX.dll")

mydll = cdll.LoadLibrary("XXX.dll")を交換してみてください。その場合は、CFUNCTYPEWINFUNCTYPEに切り替えます。呼び出しているAPIは、期待する内容についての詳細を提供する必要があります。

それが役立つかどうかを確認してください。

+0

私はWINFUNCTYPEに変更しましたが、エラーも存在します。 – Eric

0

ctypesはCppで動作しません。Cpp関数はextern "C"リンケージが必要です。
動作しない理由は、Cppの名前のマングリングと関係があります。あなたの関数void setCallBack(void(*)(Data &a))の名前はCppで_Z11setCallBackPFvR4DataEとなっていますが、extern "C"をその中から入れた場合(extern "C" void setCallBack(void(*)(Data &a)))、それはCのマングリングルールになりますので、setCallBackとしてマングルされます。
mydll.setCallBackを実行すると、ctypesはsetCallBackという名前の関数を探していますが、見つからず、認識できずエラーが発生する_Z11setCallBackPFvR4DataEという名前の関数が見つかりました。

0

1つのエラーは、コールバックがコールバック関数ではなくデータ構造をラッピングしていることです。変更:

def dataResponse(data): 
    print data.index 
callback = callback_type(dataResponse) 
mydll.setCallBack(callback) 

それとも、デコレータ構文を使用することができます:へ

callback_type = CFUNCTYPE(None, POINTER(Data)) 
callback = callback_type(Data) 
mydll.setCallBack(callback) 
def dataResponse(data): 
    print data.index 

@CFUNCTYPE(None, POINTER(Data)) 
def dataResponse(data): 
    print data.index 

mydll.setCallBack(dataResponse) 

はここで完全な例です。また、マングリングC++の名前を避けるためにextern "C"を使用します。

ます。test.cpp(Windowsの場合)

struct Data { 
    int index; 
}; 

typedef void (*CALLBACK)(Data&); 
CALLBACK g_callback; 

extern "C" { 
    __declspec(dllexport)void setCallBack(CALLBACK f) { 
     g_callback = f; 
    } 

    __declspec(dllexport) void func() { 
     Data d; 
     d.index = 42; 
     if(g_callback) 
      g_callback(d); 
    } 
} 

test.py

from ctypes import * 

class Data(Structure): 
    _fields_ = [('index',c_int)] 

CALLBACK = CFUNCTYPE(None,POINTER(Data)) 

dll = CDLL('test') 
dll.setCallBack.argtypes = CALLBACK, 
dll.setCallBack.restype = None 
dll.func.argtypes = None 
dll.restype = None 

@CALLBACK 
def dataResponse(data): 
    print(data.contents.index) 

dll.setCallBack(dataResponse) 
dll.func() 

出力

42 
関連する問題