Python在传感器的DLL中调用SDK函数,该函数采用指针IP和端口并返回void *(void *(用于配置文件传感器的句柄)。) [英] Python calling an SDK function in DLL of a sensor that takes pointer IP and port and return a void* (void* a handle to the profile sensor.)

查看:157
本文介绍了Python在传感器的DLL中调用SDK函数,该函数采用指针IP和端口并返回void *(void *(用于配置文件传感器的句柄)。)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚接触Python。我正在尝试通过其DLL库连接到激光传感器。该库中的SDK函数以C ++语言编译。

I am just new in Python. I am trying to connect to a laser sensor through its DLL library. The SDK functions in this Library are compiled in C++ language.

通过在python中使用ctypes我的第一个尝试是调用EthernetScanner_Connect函数。函数参数如下:

By using ctypes in python my first try is to call the EthernetScanner_Connect function. The function parameters are as follow:

void* EthernetScanner_Connect(char *chIP, char *chPort, int iTimeOut)

根据c ++中的函数说明,如果发生连接失败,则应返回NULL指针,否则应返回句柄

According to the function discription in c++ it should return NULL pointer if a failure in connection occurs, otherwise it should return the handle to the profile sensor, which is gonna be used in other functions.

我在python上的代码直到现在:

My code on python untill now:

from ctypes import *

lib=windll.LoadLibrary("c:\\EthernetScanner.dll")

if lib:
    print("the Library is loaded")

EthernetScanner_Connect = getattr(lib,"EthernetScanner_Connect")

EthernetScanner_Connect.restype = c_void_p
EthernetScanner_Connect.argtypes =[c_char_p,c_char_p,c_int]
x = EthernetScanner_Connect(b"193.164.200.1\0",b"32407\0",0)

print(x)

而我期望此函数为NULL,因为我未连接到se nsor还可以,它给了我以下信息:

while I am expecting NULL from this function because i am not connected to the sensor yet, it is giving me the following:

the Library is loaded
45940800


推荐答案

我想先指出 [Python 3.Docs]:ctypes-Python的外部函数库

我将基于一些假设发布答案:

I'm going to post an answer based on some assumptions:


  1. 您正在谈论的传感器与 [FoxControls]中所述的相同:acuity-ap820-users-manual.pdf 。如果不是这样,答案就没用了。

  2. 根据上述文档, EthernetScanner_GetConnectStatus 可能的返回状态为(强调是我的):

  1. The sensor you're talking about is the same one as described in [FoxControls]: acuity-ap820-users-manual.pdf. If this isn't true, the answer is useless
  2. According to above doc, EthernetScanner_GetConnectStatus's possible return statuses are (emphasis is mine):


状态是一个无符号整数,当
函数使用时,状态缓冲区用作包含状态代码的缓冲区
状态代码为:

Status is a unsigned integer used as a buffer to contain the status code when the function returns.
The status codes are:


  • 0:已断开连接

  • 1:正在断开连接

  • 2:正在连接

  • 3:已连接

  • 0: Disconnected
  • 1: Disconnecting
  • 2: Connecting
  • 3: Connected


基于上述,并且连接超时为0的事实,我认为(虽然 doc 中没有任何东西支持它,但是)它试图以非阻塞模式进行连接:

Based on the above, and the fact that the connect timeout is 0, I assumed (nothing in the doc to support it, though) that it tries to connect in non blocking mode:


  • EthernetScanner_Connect 返回立即(表示之前尝试连接-它安排了连接操作如果您愿意的话,可以使用 NULL 指针。对于非阻塞 async IO 示例,请检查 [MS.Docs]:连接函数

  • (上方)指针应该定期使用 EthernetScanner_GetConnectStatus 查询。这就是为什么将指针设为非 NULL 的原因(因为 EthernetScanner_Connect 返回时,连接尝试的结果尚不清楚)

  • EthernetScanner_Connect returns immediately (meaning that before attempting to connect - it "schedules" a connection operation if you will) a non NULL pointer. For a non blocking (async) IO example, check [MS.Docs]: connect function
  • The (above) pointer should be queried (periodically) using EthernetScanner_GetConnectStatus. That's why it makes sense for the pointer to be non NULL (as when EthernetScanner_Connect returns, the connection attempt result is not yet known)

这是一段应该用来解决问题的代码(不必说这是盲编码) -表示我实际上并未对其进行测试)。
由于第二个 nd 假设的结果,如果传递超时大于0 ,则 EthernetScanner_Connect 应该返回 NULL

Here's a piece of code that is supposed to deal with the problem (needless to say that it's blind coding - meaning that I didn't actually test it).
As a consequence of the 2nd assumption, if passing a timeout greater than 0, EthernetScanner_Connect should return NULL.

code.py

#!/usr/bin/env python3

import sys
import ctypes
import time


DLL_NAME = "c:\\EthernetScanner.dll"

CONNECT_STATUS_DISCONNECTED = 0
CONNECT_STATUS_DISCONNECTING = 1
CONNECT_STATUS_CONNECTING = 2
CONNECT_STATUS_CONNECTED = 3

CONNECT_STATUSES_PENDING = [
    CONNECT_STATUS_CONNECTING,
    CONNECT_STATUS_DISCONNECTING,
]

def main():

    connect_timeout_msec = 0
    nb_mode = connect_timeout_msec == 0

    dll = ctypes.WinDLL(DLL_NAME)

    EthernetScanner_Connect = dll.EthernetScanner_Connect
    EthernetScanner_Connect.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint32]
    EthernetScanner_Connect.restype = ctypes.c_void_p

    EthernetScanner_GetConnectStatus = dll.EthernetScanner_GetConnectStatus
    EthernetScanner_GetConnectStatus.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint32)]

    EthernetScanner_Disconnect = dll.EthernetScanner_Disconnect
    EthernetScanner_Disconnect.argtypes = [ctypes.c_void_p]
    EthernetScanner_Disconnect.restype = ctypes.c_uint32

    ptr = EthernetScanner_Connect(b"192.168.100.1", b"32001", connect_timeout_msec)
    if nb_mode:
        print("Non blocking mode: EthernetScanner_Connect returned {:}".format(ptr))
        poll_timeout_sec = 0.5
        connect_status = ctypes.c_int(CONNECT_STATUS_CONNECTING)
        while connect_status.value in CONNECT_STATUSES_PENDING:
            time.sleep(poll_timeout_sec)
            EthernetScanner_GetConnectStatus(ptr, ctypes.byref(connect_status))
        if connect_status.value != CONNECT_STATUS_CONNECTED:
            print("Couldn't connect (status: {:})!".format(connect_status.value))
            return
    else:
        print("Blocking mode: EthernetScanner_Connect returned {:}".format(ptr))
        if not ptr:
            print("Couldn't connect!")
            return

    # Do something with the sensor (pointer)

    EthernetScanner_Disconnect(ptr)


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()
    print("Done.")

这篇关于Python在传感器的DLL中调用SDK函数,该函数采用指针IP和端口并返回void *(void *(用于配置文件传感器的句柄)。)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆