我尝试通过DLL(由PLC制造商分发的C API接口)与PLC通信。我正在使用Python 3.1.4作为其他软件(x64 - Windows 7)中的脚本环境嵌入。
下面的回调函数在这个嵌入式脚本环境中不起作用(没有任何反应)。我已经启动并停止了脚本之后生成回调函数的触发器,然后嵌入了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'