在 Python 中加载 C++ 类

Mar*_*rco 5 c++ python dll

我正在尝试在 Python 中导入 C++ 类。我知道我可以使用 BoostPython、SWIG 或 Cython,但出于教学目的,我尝试使用extern "C". 简而言之,我正在尝试复制这一点

我的环境是 Windows 10,使用 Anaconda 3 和 Python 3.6。我已经安装了 mingw64 4.8.3 作为 C/C++ 编译器。

这是我的foo.cpp

#include <iostream>
// A simple class with a constuctor and some methods...
class Foo
{
    public:
        Foo(int);
        void bar();
        int foobar(int);
    private:
        int val;
};
Foo::Foo(int n)
{
    val = n;
}
void Foo::bar()
{
    std::cout << "Value is " << val << std::endl;
}
int Foo::foobar(int n)
{
    return val + n;
}
// Define C functions for the C++ class - as ctypes can only talk to C...
extern "C"
{
    Foo* Foo_new(int n) {return new Foo(n);}
    void Foo_bar(Foo* foo) {foo->bar();}
    int Foo_foobar(Foo* foo, int n) {return foo->foobar(n);}
}
Run Code Online (Sandbox Code Playgroud)

我是这样编译的g++ -c -fPIC foo.cpp -o foo.o:输出是:

foo.cpp:1:0: warning: -fPIC ignored for target (all code is position independent) [enabled by default]
#include <iostream>
^
Run Code Online (Sandbox Code Playgroud)

然后,我以这种方式编译:g++ -shared -Wl,-soname,libfoo.dll -o libfoo.dll foo.o没有收到错误/警告。该文件libfoo.dll已出现在文件夹中。

当我尝试使用Python时:

import ctypes
lib = ctypes.windll.LoadLibrary('libfoo.dll')
Run Code Online (Sandbox Code Playgroud)

我得到了错误OSError: [WinError 126] the specified module could not be found。我的Python工作目录就是该libfoo.dll文件夹。

我尝试创建一个简单的 C-HelloWorld 库:我以相同的方式进行编译(用一部分gcc代替g++),并成功将其加载到 Python 中。

哪里有问题?编译说明中有吗?或者在代码中?

Mar*_*rco 3

我从@Scheff 评论开始找到了一个解决方案。

在 Linux 上(我已经在 Ubuntu 16、GCC 4.4.0 和 Python 3.6 上尝试过),我的问题代码无需修改即可正常运行(无论是在代码上还是在编译指令上)。

在 Windows 上,我extern "C"以这种方式修改了块:

extern "C"
{
     __declspec(dllexport) Foo* Foo_new(int n) {return new Foo(n);}
     __declspec(dllexport) void Foo_bar(Foo* foo) {foo->bar();}
     __declspec(dllexport) int Foo_foobar(Foo* foo, int n) {return foo->foobar(n);}
}
Run Code Online (Sandbox Code Playgroud)

我像以前一样重新编译。

此后,我能够按照问题链接中所述导入模块和 C++ 类。

要实现 C++ 打印功能,请参阅此问题