【发布时间】: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——听起来很奇怪。