Ctypes回调函数不能与嵌入式python 3.1(AMD64)一起使用

时间:2013-03-18 22:03:42

标签: python callback ctypes

我尝试通过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'

0 个答案:

没有答案