ctypes.ArgumentError при вызове функций DLL с Python - PullRequest
0 голосов
/ 14 мая 2018

Я использую ctypes для вызова функций в файле DLL в соответствии с файлом описания, который описывает параметры и возврат функций DLL.Вот одна функция в этой DLL называется InitNetwork.Ниже приведено описание:

Function:BOOL InitNetwork(char  LocalIP[],char  ServerIP[],int  LocalDeviceID);
Arguments:LocalIP
           ServerIP
           LocalDeviceID
Return:Success:TRUE;
        Faile:FALSE;

То, что я делаю в Python, выглядит следующим образом:

from ctypes import *
import os

#Load Dll:
cppdll = CDLL("C:\\VS_projects\\MusicServer_Flask\\NetServerInterface.dll")

#Get the function:
initnetwork = getattr(cppdll, "?InitNetwork@@YAHQAD0H@Z")  # The function can be successfully accessed.

#specify arguments' types:
initnetwork.argtypes = [c_char_p,c_char_p,c_int]

После этого я пытаюсь:

initnetwork("192.168.1.103", "192.168.1.103", 1111)

ПолучитьОшибка:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type

Если я попробую это:

initnetwork(LocalIP = "192.168.1.103", ServerIP = "192.168.1.103", LocalDeviceID = 1111)

Я получу:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: this function takes at least 3 arguments (0 given)

Почему появляются эти ошибки?Как я могу успешно вызвать эту функцию?Любое предложение приветствуется.Спасибо за внимание!

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

ctypes официальный документ: [Python 3.5]: ctypes - библиотека сторонних функций для Python .

Создан манекен .dll для имитации вашего поведения.

dll.c

#include <stdio.h>
#include <Windows.h>


__declspec(dllexport) BOOL InitNetwork(char LocalIP[], char ServerIP[], int LocalDeviceID) {
    printf("From C:\n\tLocalIP: [%s]\n\tServerIP: [%s]\n\tLocalDeviceID: %d\n", LocalIP, ServerIP, LocalDeviceID);
    return TRUE;
}

Проверка [SO]: Как скомпилировать 64-битную DLL, написанную на C? (Ответ @ CristiFati) для получения подробных сведений о том, как его построить (были сделаны те же самые шаги, команда в этом случае была: cl /nologo /LD /DWIN64 /DWIN32 /Tp dll.c /link /OUT:NetServerInterface.dll).

(основная) проблема заключается в том, что в Python3 , char* больше не отображается на строку , а на байт объект.

code.py

import sys
import ctypes
from ctypes import wintypes


FILE_NAME = "NetServerInterface.dll"
FUNC_NAME = "?InitNetwork@@YAHQEAD0H@Z"  # Name different than yours: if func was declared as `extern "C"`, the "normal" name would be required


def main():
    net_server_interface_dll = ctypes.CDLL(FILE_NAME)
    init_network = getattr(net_server_interface_dll, FUNC_NAME)

    init_network.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int]
    init_network.restype = wintypes.BOOL

    init_network(b"192.168.1.103", b"192.168.1.103", 1111)


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

выход

(py35x64_test) e:\Work\Dev\StackOverflow\q050325050>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py
Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32

From C:
        LocalIP: [192.168.1.103]
        ServerIP: [192.168.1.103]
        LocalDeviceID: 1111
0 голосов
/ 14 мая 2018

Я думаю, что проблема в вашем интерфейсе C ++.Я думаю, что если вы измените его на функцию: BOOL InitNetwork (char * LocalIP, char * ServerIP, int LocalDeviceID);

ваш первый вызов (без ключевых слов) должен работать, но я думаю, что вам может потребоваться удалить кавычкивокруг последнего аргумента (в конце концов, это int).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...