使用 ctypes 的 .dll 中的 python 中的 C++ 函数 - 未找到函数并且访问冲突
Posted
技术标签:
【中文标题】使用 ctypes 的 .dll 中的 python 中的 C++ 函数 - 未找到函数并且访问冲突【英文标题】:C++ function in python from .dll using ctypes - function not found and access violation 【发布时间】:2017-05-26 23:01:44 【问题描述】:我有一个名为 hello.cpp
的简单 C++ 代码,它具有打印“Hello world”的功能
#include <iostream>
void hello_world();
int main()
std::cout << "Start" << std::endl;
void hello_world()
std::cout << "Hello world" << std::endl;
我使用以下方法构建 .dll (~1.9mb):
g++ -c hello.cpp
g++ -static -fPIC -o hello.dll hello.o
(尝试在 python 中访问时使用-shared
会给出WinError 126 ... module not found
)
python代码是:
from ctypes import cdll
lib = cdll.LoadLibrary('hello.dll')
lib.hello_world()
这会引发以下错误:
AttributeError: function 'hello_world' not found
我读到有人提到__declspec(dllexport)
包装器是必要的,extern "C"
也是如此,这样代码才不会“损坏”。所以现在使用它作为代码:
#include <iostream>
extern "C"
__declspec(dllexport) void hello_world();
int main()
std::cout << "Opened" << std::endl;
void hello_world()
std::cout << "hello world" << std::endl;
python 行 lib.hello_world()
现在引发:
OSError: exception: access violation writing 0x000E28A0
这里有什么问题?如何让 python 识别和运行 .dll 中的 C++ 函数?我可以跳过中间人并以某种方式从 .cpp 文件或 .o 文件运行 C++ 函数吗?
编辑:
使用 eryksun 的答案,事实证明不需要 dllexport。外部“C”是必须的
【问题讨论】:
1:您正在混合 c 编译器和 C (C++) 运行时 (Python 是用 VStudio 编译的,而你的 .dll 是用 g++ 编译的)。 2:您的 .dll 有一个main
函数,可以将其限定为可执行文件(更不用说缺少 -shared
链接器标志)。
@CristiFati 将我的 C++ 代码中的函数名称从 main 更改为其他任何名称都会在 g++ 进程的第二步时给我一个undefined reference to `WinMain@16'
错误。能否详细说明一下“Python是用VStudio编译的”?
这通常是因为您正在构建一个 Windows 应用程序(检查 [MSDN]: /SUBSYSTEM (Specify Subsystem) 链接器标志)。
在这种情况下我应该构建 Windows 应用程序吗?我不知道 .o 或 .dll 被视为应用程序。如果是或者即使不是,我应该用 g++ 做什么来代替?
试试-static -shared
——听起来很奇怪。
【参考方案1】:
感谢@eryksun,在这种情况下,通过这样的编译解决了这个问题:
g++ -c hello.cpp
g++ -static -shared -o hello.dll hello.o
像这样设置 C++ 代码:
#include <iostream>
int main()
std::cout << "Opened" << std::endl;
void hello_world()
std::cout << "hello world" << std::endl;
extern "C"
void hello_world();
像往常一样从 Python 运行它:
from ctypes import cdll
lib = cdll.LoadLibrary('hello.dll')
lib.hello_world()
【讨论】:
以上是关于使用 ctypes 的 .dll 中的 python 中的 C++ 函数 - 未找到函数并且访问冲突的主要内容,如果未能解决你的问题,请参考以下文章
在 python 中的 byref 向量参数上使用 ctypes 进行 DLL 转换
使用 ctypes 的 .dll 中的 python 中的 C++ 函数 - 未找到函数并且访问冲突