使用ctypes提取返回参数

2024-09-29 23:20:29 发布

您现在位置:Python中文网/ 问答频道 /正文

前言:我对Python相当熟悉,但直到一周前我才接触过C语言。。。现在我正试着用ctypes和电机控制器通话。在

所以我一直在玩这个特殊的函数(VCS GetProtocolStackSettings),直到最近才开始工作。我的问题是,尽管它返回的是“1”(即根据下面的规范成功),但我似乎无法访问返回参数。在

这是我的密码。您可以看到,我将返回参数存储在指向uint32对象的指针中,只是不知道如何获取它们。在

lib=ctypes.WinDLL('C:\\Program Files (x86)\\maxon motor ag\\EPOS Positioning Controller\\EPOS2\\04 Programming\\Windows DLL\\EposCmd64.dll')

typeDict={  'char': ctypes.c_char,
        'char*': ctypes.c_char_p,
        '__int8': ctypes.c_int8,
        'BYTE': ctypes.c_uint8,
        'short': ctypes.c_int16,
        'WORD': ctypes.c_uint16,
        'long': ctypes.c_int32,
        'DWORD': ctypes.c_uint32,
        'BOOL': ctypes.c_int32,
        'HANDLE': ctypes.POINTER(ctypes.c_uint32)
        }

def VCS_GetProtocolStackSettings(KeyHandle):
    '''Returns the communication parameters 'baudrate and 
        'timeout'
    '''

    func=lib['VCS_GetProtocolStackSettings']
    func.argtypes
    func.restype=typeDict['BOOL']   

    pBaudrate=ctypes.pointer(typeDict['DWORD']())
    pTimeout=ctypes.pointer(typeDict['DWORD']())
    pErrorCode=ctypes.pointer(typeDict['DWORD']())

    cKeyHandle=typeDict['HANDLE'](KeyHandle)

    return func(KeyHandle,pBaudrate,pTimeout,pErrorCode)

enter image description here


Tags: 参数libvcsctypesint8boolfuncchar
2条回答

如果要测试ctypes,最好制作一个虚拟DLL。例如,函数的原型是(我发现它是here):

     Initialisation_DllExport BOOL __stdcall VCS_GetProtocolStackSettings(HANDLE KeyHandle, DWORD* pBaudrate, DWORD* pTimeout, DWORD* pErrorCode); 

虚拟DLL将是:

^{pr2}$

所以我们的python代码是:

#!python

from ctypes import *

BOOL   = c_int
DWORD  = c_ulong
HANDLE = c_void_p

lib = WinDLL('./lib.dll')

# BOOL __stdcall VCS_GetProtocolStackSettings(HANDLE KeyHandle,
#                                             DWORD* pBaudrate,
#                                             DWORD* pTimeout,
#                                             DWORD* pErrorCode);

VCS_GetProtocolStackSettings = lib['VCS_GetProtocolStackSettings']
VCS_GetProtocolStackSettings.restype  = BOOL
VCS_GetProtocolStackSettings.argtypes = [HANDLE,
                                         POINTER(DWORD),
                                         POINTER(DWORD),
                                         POINTER(DWORD)]

KeyHandle = HANDLE(123)
Baudrate  = DWORD(0)
Timeout   = DWORD(0)
ErrorCode = DWORD(0)

result = BOOL(VCS_GetProtocolStackSettings(KeyHandle,
                                           byref(Baudrate),
                                           byref(Timeout),
                                           byref(ErrorCode)))

print(Baudrate.value)
print(Timeout.value)
print(ErrorCode.value)
print(result.value)

如果运行它:

> python example.py
123
1
2
3
4
>

pBaudrate.contents.value将访问指针中的值,但您只需要一个c_uint()并通过引用函数传递它。下面是一个例子。这也是一个通过在失败时抛出异常使函数更“python”的示例。在

import ctypes
from ctypes import wintypes

lib = ctypes.WinDLL(dllnamehere)
lib.VCS_GetProtocolStackSettings.argtypes = [wintypes.HANDLE,wintypes.PDWORD,wintypes.PDWORD,wintypes.PDWORD]
lib.VCS_GetProtocolStackSettings.restype = wintypes.BOOL

def VCS_GetProtocolStackSettings(KeyHandle):
    baudrate = wintypes.DWORD()
    timeout = wintypes.DWORD()
    errorcode = wintypes.DWORD()
    result = lib.VCS_GetProtocolStackSettings(KeyHandle,ctypes.byref(baudrate),ctypes.byref(timeout),ctypes.byref(errorcode))
    if not result:
        raise RuntimeError('error code = {}'.format(errorcode.value))
    return baudrate.value,timeout.value

请注意,WinDLL是否合适。Windows系统DLL使用__stdcall调用约定,但许多DLL使用__cdecl调用约定,而您将使用CDLL。在

相关问题 更多 >

    热门问题