当前位置: 首页 > 面试题库 >

使用Python调用DLL函数时出现ctypes.ArgumentError

余铭晨
2023-03-14
问题内容

我使用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)

为什么会出现这些错误?如何成功调用此函数?任何建议表示赞赏。感谢您的关注!


问题答案:

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]:如何编译用C编写的64位dll?(@CristiFati的答案)以获取有关如何构建它的详细信息(采取了完全相同的步骤,在这种情况下,命令是:)cl /nologo /LD /DWIN64 /DWIN32 /Tp dll.c /link /OUT:NetServerInterface.dll

(主要)问题在于,在 Python3中char*不再映射到 string ,而是映射到 bytes 对象。

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


 类似资料:
  • 问题内容: 我正在编写一个调用Windows DLL的Go应用程序。该DLL是用MSVC编写的,并且使用__declspec(dllexport)具有外部“ C”导出。 我的Go应用程序的顶部如下: 我从这样的模块中调用函数: 问题是,当我尝试运行此应用程序时,出现以下错误: 我用DUMPBIN查看了DLL导出的符号,它确切显示了“moduleImpl_len”作为导出的符号。这也是MyModul

  • 本文向大家介绍.NET Framework 调用Win32 dll函数,包括了.NET Framework 调用Win32 dll函数的使用技巧和注意事项,需要的朋友参考一下 示例 声明一个功能static externsttingDllImportAttribute其Value属性设置为.dll文件的名称。不要忘记使用System.Runtime.InteropServices名称空间。然后将其

  • 问题内容: 我正在Python中调用一个函数,该函数可能会停滞并迫使我重新启动脚本。 如何调用该函数或将其包装在其中,以便如果花费的时间超过5秒,脚本将取消该函数并执行其他操作? 问题答案: 如果在上运行,则可以使用信号包: 调用后10秒钟,将调用处理程序。这引发了一个异常,你可以从常规Python代码中拦截该异常。 该模块不能很好地与线程配合使用(但是,谁可以呢?) 请注意,由于发生超时时会引发

  • 本文向大家介绍windows下使用Xshell时出现丢失msvcr110.dll等dll问题,包括了windows下使用Xshell时出现丢失msvcr110.dll等dll问题的使用技巧和注意事项,需要的朋友参考一下 启动程序报错如下:无法启动此程序,因为计算机中丢失MSVCR110.dll。尝试重新安装该程序以解决此问题。应该很容易就搜索到,缺少这样的dll文件,是没有安装Visual C++

  • 我有一个网页,其中有一个按钮打开一个小的排序窗口,我必须在那里作为和并且我想要使用以便用户可以选择日期,而不是手动在字段中键入它。但是,当用户单击该输入字段时,datepicker不会显示。以下是我到目前为止所拥有的(对于js、html、jquery来说是非常新的):

  • 情境:我有一个实现了JNI的dll,我想从一个Cpp应用程序调用其中的方法。 当前状态:根据我的理解,一个实现了JNI的dll实际上与JAVA无关,例如:在test.JAVA中,我编写了 并在testdll.cp 我认为这样的程序与JVM无关,jint结构似乎已经在JNI.h中完全定义了。 因此,我想知道是否可以直接调用而不从Cpp应用程序创建VM,如果可以,请: 参数列表中的`jnienv*`和