使用ctypes包装DLL函数

2024-10-01 02:29:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我现在在C++的DLL中包装了一些函数,这些原始的.H.A.CPP文件是不可访问的。在学习了ctypes教程之后,我仍然有一些问题。我给你举个例子: 这是来自dll函数的描述文件,只告诉函数的名称、效果和参数:

#initialize network:
BOOL InitNetwork(char LocalIP[],char ServerIP[],int LocalDeviceID)

#judging if the server is online after network initialization:
BOOL GetOnlineStatus()

#get song name:
char* GetMusicSongName(int DirIndex,int SongIndex)

#making the device playing music:
int PlayServerMusic(int DirIndex,int MusicIndex,int DeviceCout,PUINT lpDeviceID,int UseListIndex,int UserMusicIndex,UINT TaskCode)

为了在Python中包装这些函数,我要做的是:

^{pr2}$

当我在VS2015 python interactice窗口中输入并定义第一个函数(导入包并加载dll之后),它会给我一个错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'c_char' is not defined

我需要指定输入参数的类型吗?如果是,怎么做?我无法识别第四个函数中某些参数的类型,例如PUINT lpDeviceIDUINT TaskCode。如何指定它们? 此外,是否需要指定函数的返回值类型?如果是,如何指定它们? 有人能给我上面例子的正确包装代码吗?感谢您的关注!在


Tags: 文件the函数name类型参数isnetwork
2条回答

你的问题是你没有很好的名称空间。它

cppdll.InitNetwork.argtypes = [ctypes.c_char, ctypes.c_char, ctypes.c_int]

您可以将所需的ctypes数据直接导入模块中。而且由于ctypes为您创建了函数包装器,您不需要自己的def来完成相同的操作。您可以使用cppdll.Whatever调用它们,但是如果您喜欢在名称空间级别上使用函数,则可以为它们创建变量。在

^{pr2}$

这里有一整套应该有用的定义。注意如何通过创建类型的实例并通过引用传递它来传递输出参数。许多常见的窗口类型也在ctypes.wintypes中定义。在

注意,对于InitNetwork,第一个参数类型是C中的char*,因此您需要c_char_p而不是{},并且可以直接传递Python字节字符串,就像C代码不写入指针一样。ctypes.create_string_buffer()可用于在需要时生成可写字符数组。在

from ctypes import *
from ctypes import wintypes as w

dll = WinDLL('path/to/dll')

# BOOL InitNetwork(char LocalIP[],char ServerIP[],int LocalDeviceID)
dll.InitNetwork.argtypes = c_char_p,c_char_p,c_int
dll.InitNetwork.restype = w.BOOL

# BOOL GetOnlineStatus()
dll.GetOnlineStatus.argtypes = None
dll.GetOnlineStatus.restype = w.BOOL

# char* GetMusicSongName(int DirIndex,int SongIndex)
dll.GetMusicSongName.argtypes = c_int,c_int
dll.GetMusicSongName.restype = c_char_p

# int PlayServerMusic(int DirIndex,int MusicIndex,int DeviceCout,PUINT lpDeviceID,int UseListIndex,int UserMusicIndex,UINT TaskCode)
dll.PlayServerMusic.argtypes = c_int,c_int,w.PUINT,c_int,c_int,w.UINT
dll.PlayServerMusic.restype = c_int

dll.InitNetwork(b'1.1.1.1',b'2.2.2.2',7)
status = dll.GetOnlineStatus()
song = dll.GetMusicSongName(1,2)
DeviceCout = w.UINT()
result = dll.PlayServerMusic(1,2,3,byref(DeviceCout),4,5,6)

相关问题 更多 >