2

DLL (PLC の製造元によって配布される C API インターフェイス) を介して PLC と通信しようとしています。他のソフトウェア (x64 - Windows 7) にスクリプト環境として組み込まれている Python 3.1.4 を使用しています。

以下のコールバック関数は、この組み込みスクリプト環境では機能しません (何も起こりません)。コールバック関数のトリガーが生成された後、スクリプトが開始および停止された後、Python が埋め込まれたソフトウェアが完全にクラッシュします。

コードは、スタンドアロンの python (3.1.4 MSC v1500 64 ビット AMD も同様) で正常に動作します。

組み込み Python でコールバックを使用しない DLL の他の関数を正常に実装しました。

それが何であるかを知っている人はいますか?

def callback_func(amsaddr,notifHeader,huser):
    print('do something')
    pass

CMPFUNC = WINFUNCTYPE(None,POINTER(AmsAddr),POINTER(AdsNotificationHeader),c_ulong)
cmp_func = CMPFUNC(callback_func) 


netId =  AmsNetId((c_ubyte*6)(5,18,18,27,1,1))
plcAddress = AmsAddr(netId,801)
nIndexGroup = c_ulong(0xF021)
nIndexOffset = c_ulong(0x0)
adsNotif = AdsNotificationAttrib(1,4,1000000,1000000)
handle = c_ulong()
huser = c_ulong(10)

ADS_DLL = WinDLL("C:/Program Files/TwinCAT/Ads Api/TcAdsDll/x64/TcAdsDll.dll")
ADS_DLL.AdsSyncAddDeviceNotificationReq.argtypes=[POINTER(AmsAddr),c_ulong,c_ulong,POINTER(AdsNotificationAttrib),CMPFUNC,c_ulong,POINTER(c_ulong)]
ADS_DLL.AdsSyncAddDeviceNotificationReq.restype=c_long

#Function in the DLL with the callback
errCode = ADS_DLL.AdsSyncAddDeviceNotificationReq(pointer(plcAddress),nIndexGroup,nIndexOffset,pointer(adsNotif),cmp_func,huser,pointer(handle))
print('Device Notification error Code : %s' %errCode)

編集 ^2

単純な ctypes コールバックを試してみましたが、組み込みの python バージョンでは惨めに失敗しました...ソフトウェアがハングするだけで、タスクマネージャーでそれを強制終了する必要があります。次のコードを試しました(ドキュメントから):

from ctypes import *
IntArray5 = c_int * 5
ia = IntArray5(5, 1, 7, 33, 99)

libc = cdll.msvcrt #or libc = cdll.msvcr90  --> same problem
qsort = libc.qsort
qsort.restype = None

CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
def py_cmp_func(a, b):
    print("py_cmp_func", a[0], b[0])
    return 0
cmp_func = CMPFUNC(py_cmp_func)

qsort(ia, len(ia), sizeof(c_int), cmp_func)

編集 ^3

スレッドを使用していくつかの改善を得ることができました。print() 関数だけがコールバックで何も出力しません...たとえば、 os.system('c:/windows/notepad.exe') などの他の関数も機能しません。

from ctypes import *
import threading, queue
import os
IntArray5 = c_int * 5
ia = IntArray5(5, 1, 7, 33, 99)
libc = cdll.msvcrt
qsort = libc.qsort
qsort.restype = None

q = queue.Queue()

CMPFUNC = CFUNCTYPE(None,POINTER(c_int), POINTER(c_int))
def py_cmp_func(a, b):
    print("py_cmp_func", a[0], b[0]) #--> doesn't print anything
    print('Callback, in thread %s' % threading.current_thread().name) #--> doesn't print anything
    q.put('something')

cmp_func = CMPFUNC(py_cmp_func)
t = threading.Thread(target=qsort, args=(ia, len(ia), sizeof(c_int), cmp_func))
t.start()
print(threading.enumerate()) #--> prints [<Thread(Thread-1, started 2068)>, <_MainThread(MainThread, started 2956)>] 
t.join()
print(threading.enumerate()) # --> prints [<_MainThread(MainThread, started 2956)>]
print(q.get()) #--> prints 'something'
4

0 に答える 0