Python, ctypes, как исправить: OSError: исключение: запись нарушения прав доступа 0x0000000000000000 - PullRequest
0 голосов
/ 02 февраля 2020

Я пытаюсь настроить соединение программы Python с торговым терминалом (QUIK), используя эту официальную dll: http://arqatech.com/upload/iblock/80a/Trans2QuikAPI_1.3_x64.zip. Для этого dll нет удобного соединения с python, но я нашел оболочку python, написанную 10 лет go для этой dll предыдущей версии: https://pypi.org/project/PyQUIK/. Предыдущие версии dll были 32-битными, а новые 64-битные, старые версии вообще не запускались, когда я пробовал новую версию dll, она работала, но постоянно выдает ошибки:

Traceback (most recent call last):

File "_ctypes/callbacks.c", line 232, in 'calling callback function'

OSError: exception: access violation writing 0x0000000000000000

Ошибка возникает только тогда, когда торговый терминал, к которому пытается подключиться dll, готов принимать транзакции от dll. Когда терминал не принимает транзакции, ошибок не возникает. В этом случае ошибки возникают на этапе подключения к терминалу и когда соединение с ним прекращается. Сообщения об ошибках говорят о ctypes, но я не знаком ни с этой библиотекой, ни с языком C, поэтому не знаю, как решить эту проблему. Вот часть кода, которая вызывает ошибку:

from ctypes import WinDLL, c_char, c_long, c_double, POINTER, \
     WINFUNCTYPE, byref, create_string_buffer, pointer, string_at
from ctypes.wintypes import LPCSTR, LPSTR, DWORD, CHAR, PDWORD
from ctypes.util import find_library

c_long_p = POINTER(c_long)
c_double_p = POINTER(c_double)
c_void = None


try:
    TRANS2QUIK = WinDLL("TRANS2QUIK.dll")
except OSError:
    import os
    libpath = os.path.join(os.path.dirname(__file__), "TRANS2QUIK.dll")
    TRANS2QUIK = WinDLL(libpath)


pnExtendedErrorCode_data = c_long()
pnExtendedErrorCode = byref(pnExtendedErrorCode_data)
pnReplyCode_data = c_long()
pnReplyCode = byref(pnReplyCode_data)
pdOrderNum_data = c_double()
pdOrderNum = byref(pdOrderNum_data)

dwErrorMessageSize = DWORD(200)
dwResultMessageSize = DWORD(200)
lpstrErrorMessage = create_string_buffer(dwErrorMessageSize.value)
lpstrResultMessage = create_string_buffer(dwResultMessageSize.value)


def _declare_extended(func, *args):
    func.restype = c_long
    func.argtypes = args + (c_long_p, LPSTR, DWORD)
    def __caller__(*args):
        args += (
            pnExtendedErrorCode,
            lpstrErrorMessage,
            dwErrorMessageSize
        )
        return func(*args)
    return __caller__


def _declare_method(func, restype, *args):
    func.restype = restype
    func.argtypes = args
    return func


# long TRANS2QUIK_CONNECT(
#     LPCSTR lpcstrConnectionParamsString,
#     _________________________
#     long* pnExtendedErrorCode,
#     LPSTR lpstrErrorMessage,
#     DWORD dwErrorMessageSize
# )
CONNECT = _declare_extended(
    TRANS2QUIK.TRANS2QUIK_CONNECT, LPCSTR
)

def connect(path):
    lpcstrConnectionParamsString = LPCSTR(path.encode())
    return CONNECT(lpcstrConnectionParamsString)

# long TRANS2QUIK_DISCONNECT(
#     _________________________
#     long* pnExtendedErrorCode,
#     LPSTR lpstrErrorMessage,
#     DWORD dwErrorMessageSize
# )
disconnect = DISCONNECT = _declare_extended(
    TRANS2QUIK.TRANS2QUIK_DISCONNECT
)

connection = connect("C:\SBERBANK\QUIK")
print(connection)
disconnect = disconnect()
print(disconnect)

Я использую python версию 3.7.6, библиотеки ctypes версии 1.1.0, windows 10 64 бит

У меня есть опыт программирования python около года, я тоже не профессионал в Engli sh, поэтому извините, если что-то не так, это ошибка Google переводчика.

...