【问题标题】:How can I find the required parameters for a function imported from a DLL file using ctypes?如何找到使用 ctypes 从 DLL 文件导入的函数所需的参数?
【发布时间】:2020-03-12 18:11:42
【问题描述】:

我正在尝试使用 Maxon 提供的库来运行一些电机控制器。该库是我正在使用 ctypes 和 pythonNet 读取的 DLL 文件。该库正在运行,我可以驱动电机,到目前为止我使用的大多数功能都很好。但是,要从控制器读取位置数据,我需要使用一个名为 VcsGetObject 的函数。我对该函数的每次调用都会导致错误,因为我没有正确的输入或输出:

TypeError: 没有方法匹配 VcsGetObject 的给定参数

VcsGetObject 函数通过引用接受数据输入,并通过该变量返回位置数据。我尝试了各种将数据传递给函数的方法,但还没有成功。我已经尝试为函数提供额外的输出,因为我已经读过 PythonNet 可以自动执行此操作。我尝试过传入元组或列表,或者使用 ctypes.byref() 传递 ctypes 数据类型。

老实说,我不确定问题出在哪里,我想知道是否有某种方法可以查看函数的预期内容。我有 C++ 函数的文档,但因为我是从 DLL 导入它我真的说不出问题出在哪里。对于这个问题的含糊之处,我深表歉意,老实说,我觉得有很多地方可能会出错,但也许有一些非常明显的事情我只是不知道。

import time
import clr #pythonnet, manually installed with a downloaded wheel and pip
import ctypes #module to open dll files
import System
clr.AddReference('EposCmd.Net')
EposCmd64 = ctypes.CDLL('.\EposCmd64.dll')
from EposCmd.Net.VcsWrapper import Device

print("START")
print()

Device.Init()
nodeID = 1
baudrate = 1000000
timeout = 500
errorCode = 0
index = int('0x606C',16)
subindex = 0
dataLength = 4

# These functions all work as expected, so the library is being imported correctly
keyHandle, error = Device.VcsOpenDevice('EPOS4', 'MAXON SERIAL V2', 'USB', 'USB0', errorCode) #opens EPOS
print(errorCode)
Device.VcsSetProtocolStackSettings(keyHandle, baudrate, timeout, errorCode) #set baudrate
Device.VcsClearFault(keyHandle, nodeID, errorCode) #clear all faults

# # Trying to use lists or tuples doesn't work
#data = [0]
#readLength = [0]
#output = Device.VcsGetObject(keyHandle,nodeID,index,subindex,data,readLength,errorCode)

# # Using ctypes and .byref(), also doesn't work
#data = ctypes.c_byte()
#readLength = ctypes.c_byte()
#output = Device.VcsGetObject(keyHandle,nodeID,index,subindex,ctypes.byref(data),ctypes.byref(readLength),errorCode)

# # Trying to use PythonNet to turn by ref inputs into outputs
output, data, readLength = Device.VcsGetObject(keyHandle,nodeID,index,subindex,errorCode)
#print(data)
#print(readLength)

我已经包含到 maxon 文档的链接,GetObject 在第 4.1.4 节中。 https://www.maxongroup.com/medias/sys_master/8823917281310.pdf

【问题讨论】:

    标签: python pass-by-reference ctypes python.net


    【解决方案1】:

    首先,您的函数调用看起来不正确。这是未经测试的,但您的开放设备调用应该看起来更像:

    from ctypes import byref, c_byte, c_void_p
    from ctypes.wintypes import WORD, DWORD
    
    # Set type
    errorCode = DWORD()
    
    # Pass error by reference
    handle = Device.VcsOpenDevice(
        'EPOS4',
        'MAXON SERIAL V2',
        'USB',
        'USB0',
        byref(errorCode))
    
    # Read error code after function call
    print(errorCode.value)
    

    根据您的链接文档VCS_GetObject 看起来像这样:

    nodeId = WORD(1)
    objectIndex = WORD(0x606C)
    objectSubIndex = c_byte(0)
    NbOfBytesToRead = DWORD(
    data = c_void_p()
    # Vary this to read more or less data
    NbOfBytesToRead = DWORD(4)
    NbOfBytesRead = DWORD()
    errorCode = DWORD()
    
    return_value = Device.VcsGetObject(
        handle,
        nodeId,
        objectIndex,
        objectSubIndex,
        byref(data),
        NbOfBytesToRead,
        byref(NbOfBytesRead),
        byref(errorCode))
    
    print(errorCode.value)
    

    你还应该设置你的 restype 和 argtypes。

    【讨论】:

      猜你喜欢
      • 2021-11-17
      • 2011-02-22
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 2016-01-28
      • 1970-01-01
      • 2021-11-03
      • 1970-01-01
      相关资源
      最近更新 更多