Python вызывает функцию SDK в DLL датчика, который берет IP-адрес и порт указателя и возвращает void * (void * дескриптор датчика профиля). - PullRequest
1 голос
/ 26 апреля 2019

Я просто новичок в Python. Я пытаюсь подключиться к лазерному датчику через его библиотеку DLL. Функции SDK в этой библиотеке скомпилированы на языке C ++.

При использовании ctypes в python моя первая попытка - вызвать функцию EthernetScanner_Connect. Параметры функции следующие:

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

Согласно описанию функции в c ++ он должен возвращать указатель NULL в случае сбоя соединения, в противном случае он должен возвращать дескриптор датчика профиля, который будет использоваться в других функциях.

Мой код на python до сих пор:

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 от этой функции, потому что я еще не подключен к датчику, он дает мне следующее:

the Library is loaded
45940800

1 Ответ

0 голосов
/ 30 апреля 2019

Я хочу начать с указания [Python 3.Docs]: ctypes - библиотека сторонних функций для Python .

Я собираюсь опубликовать ответ, основанный на некоторых предположениях:

  1. Сенсор, о котором вы говорите, тот же, что и описанный в [FoxControls]: acuity-ap820-users-manual.pdf .Если это не так, то ответ бесполезен
  2. Согласно приведенному выше документу, EthernetScanner_GetConnectStatus возможные статусы возврата ( выделение - мое):

    Состояние - это целое число без знака, используемое в качестве буфера для хранения кода состояния при возврате функции.
    Коды состояния:

    • 0: отключено
    • 1: отключение
    • 2: подключение
    • 3: подключение


    Исходя из вышеизложенного и того факта, что тайм-аут соединения равен 0, я предположил ( ничего в doc для поддержки , хотя), что он пытается подключиться в неблокирующий режим :

    • EthernetScanner_Connect возвращает немедленно (что означает, что до пытается подключиться - он "планирует"операция подключения, если хотите) указатель не NULL .Для неблокирующего ( асинхронного ) IO , например, проверьте [MS.Docs]: функция соединения
    • (выше) указатель должен запрашиваться (периодически) с использованием EthernetScanner_GetConnectStatus .Вот почему имеет смысл указатель не NULL (например, когда возвращается EthernetScanner_Connect , результат попытки подключения еще не известен)

Вот фрагмент кода, который должен решить проблему (не говоря уже о том, что это слепое кодирование - это означает, что я на самом деле его не тестировал).
Вследствие предположения 2 nd , если время ожидания превышает больше 0 , EthernetScanner_Connect должно вернуть 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.")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...