使用ctypes从.dll文件中调用C++函数——找不到函数且出现访问冲突。

3

我有一个简单的C++代码,名为hello.cpp,其中有一个打印“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

使用-shared在Python中访问时,会出现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",以确保代码不会被"mangled"。因此现在使用以下代码:

#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。但extern "C"是必须的。

通常这是因为你正在构建一个Windows应用程序(请检查MSDN:/SUBSYSTEM(指定子系统)链接器标志)。 - undefined
找不到的 DLL 可能是 C++ 标准库。尝试添加选项 -static-libstdc++ - undefined
使用 objdump -p hello.dll | grep "DLL Name" 命令检查依赖项。 - undefined
2
尝试使用“-static -shared”这个奇怪的选项。 - undefined
1
@eryksun那个方法有效!请将这个作为答案,这样就不会被埋在评论中了。非常感谢你的帮助! - undefined
显示剩余9条评论
1个回答

4
感谢 @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()

放在最上方声明,而不是最后,这样它才能工作。至少对我来说,这个改变有影响... - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接