8

私はdll関数を呼び出すためのPythonコードを書き込もうとしていますが、typedefコールバック関数または関数ポインタに関連していると思われる以下の関数で立ち往生しています。

以下のコードをテストしました。コールバック関数が呼び出されると、python がクラッシュし (ウィンドウ通知 -- python.exe が応答を停止しました)、デバッグ メッセージは表示されません。

私は深く混乱しています、どんな助けも感謝します:)

ありがとう!

子:

#ifdef O_Win32
/** @cond */
#ifdef P_EXPORTS
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif // #ifdef P_EXPORTS
/** @endcond */
#endif // #ifdef O_Win32

// Type definition
typedef void (__stdcall *StatusCB)(int nErrorCode, int nSID, void *pArg);

//Function 
void GetStatus(StatusCB StatusFn, void *pArg);

パイソン:

from ctypes import *

def StatusCB(nErrorCode, nSID, pArg):
    print 'Hello world'

def start():
    lib = cdll.LoadLibrary('API.dll')
    CMPFUNC = WINFUNCTYPE(c_int, c_int, c_void_p)
    cmp_func = CMPFUNC(StatusCB)
    status_func = lib.GetStatus
    status_func(cmp_func)
4

1 に答える 1

13

コールバック タイプのシグネチャが間違っています。結果の型を忘れました。関数の終了時にもガベージ コレクションが行われます。グローバルにする必要があります。

GetStatus呼び出しに引数がありませんpArg。さらに、 を定義する必要があるポインターを操作する場合argtypes、そうしないと、64 ビット プラットフォームで問題が発生します。ctypes のデフォルトの引数の型は Cintです。

from ctypes import * 

api = CDLL('API.dll')
StatusCB = WINFUNCTYPE(None, c_int, c_int, c_void_p)

GetStatus = api.GetStatus
GetStatus.argtypes = [StatusCB, c_void_p]
GetStatus.restype = None

def status_fn(nErrorCode, nSID, pArg):        
    print 'Hello world'
    print pArg[0]  # 42?

# reference the callback to keep it alive
_status_fn = StatusCB(status_fn)

arg = c_int(42) # passed to callback?    

def start():        
    GetStatus(_status_fn, byref(arg))
于 2013-07-31T23:07:14.637 に答える