繁体   English   中英

从Python调用的C ++ dll

[英]C++ dll called from Python

我已经使用了使用MFC的C ++ dll,我想从python调用它。 该dll在.h文件中包含此标头

LONG CommOpen(BYTE port, LONG baud_rate);

然后我在免费软件dllexp中看到我的函数在二进制文件中称为?CommOpen @ CFIPcmd @@ QAEJEJ @ Z,因此在python中执行操作时未报告任何错误

import ctypes

lib = ctypes.WinDLL('C:\\Users\\toto\\FIProtocol.dll')
prototype = WINFUNCTYPE(c_long, c_byte, c_long)
testPt = ctypes.WINFUNCTYPE (prototype) 
testApi = testPt (("?CommOpen@CFIPcmd@@QAEJEJ@Z", lib))

直到它似乎起作用为止,但是我想在Python中将C等效为

Long l= CommOpen(5 ,115200);

但是我没有找到如何进行的方法。 任何帮助将非常感激!!

给定问题中提供的信息,解决方案是:

import ctypes

lib = ctypes.CDLL(r'C:\Users\toto\FIProtocol.dll')
CommOpen = getattr(lib, "?CommOpen@CFIPcmd@@QAEJEJ@Z")
CommOpen.argtypes = [c_byte, c_long]
CommOpen.restype = c_long

现在可以调用:

l = CommOpen(5 ,115200)

一些注意事项:

  1. 使用CDLL而不是WinDLL因为该函数使用默认的cdecl调用约定。
  2. 使用getattr可以指定错误的名称。
  3. 它总是需要明确指定argtypesrestype

但是,这说明您有更大的问题。 以上内容是根据您的函数是非成员函数编写的。 鉴于ctypes要求函数为非成员或静态的,因此这是一个合理的假设。

但是,当我将托管函数名称放入demanger中时(例如http://pear.warosu.org/c++filtjs/ ),该函数实际上是:

public: long __thiscall CFIPcmd::CommOpen(unsigned char,long)

那是C ++对象的成员函数。 无法从ctypes访问。 您需要创建一个普通的C样式包装器,或者找到一种不同的互操作方法。

根据http://docs.python.org/2/library/ctypes.html#calling-functions的说法,“您可以像调用其他任何Python一样调用这些函数。” 我建议运行一个交互式Python控制台(如ipython)并自己检查一下。

好吧,我刚刚将Python安装到VirtualBox Win32中并检查了示例:

>>> from ctypes import *
>>> f = getattr(cdll.msvcrt, "??2@YAPAXI@Z")
>>> f
<_FuncPtr object at 0x00B7EDC8>
>>> f()
24969248
>>> _

因此,是的,您可以像在python环境中调用其他函数一样调用这些函数对象。 就像文档声称的那样:)

_cputws同样起作用:

>>> cputws = getattr(cdll.msvcrt, "_cputws")
>>> r = cputws("Hello, World!\n")
Hello, World!
>>> r
0
>>>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM