用头文件编译 C++ class 以便在 python 中使用它?

Compile C++ class with a header file to use it in python?

我有一个 my_class.h:

// my_class.h

namespace N
{
    class my_class
    {
    public:
        void hello_world();
    };
}

有一个 my_class.cpp 文件。

// my_class.cpp

extern "C" {
    #include "my_class.h"
}
#include <iostream>

using namespace N;
using namespace std;

void my_class::hello_world()
{
    cout << "Hello, World!" << endl;
}

我想创建一个共享对象 my_class.so 文件以便在 python 中使用它。 因此,我正在使用 g++ 编译器。

g++ -fPIC -shared -o my_class.so my_class.cpp

使用 python my_class.so

中的共享对象
import ctypes

my_class = ctypes.cdll.LoadLibrary('./my_class.so')
my_class.hello_world

我收到以下错误消息:

Exception has occurred: AttributeError
./my_class.so: undefined symbol: hello_world

我不知道如何解释这个。
注:

要谈的很多,但我会尽量简短:

  1. extern "C" 将使这些符号在 C 语法中可用。 (你确实想要这个)
  2. C 语法不支持 classes 或命名空间。
  3. python 动态库加载器正在抓取所有符号 - 不是 只是你的 class。 (似乎命名方案有些混乱)

要修复:只需删除您的 class 和名称空间(或添加 C-API 传递)。

my_class.h

extern "C" {
   void hello_world();
}

my_class.cpp

#include "my_class.h"
#include <iostream>

void hello_world()
{
        std::cout<<"Hello, World" << std::endl;
}

构建后,使用 nm 或 objdump 验证符号 hello_world 是否已定义且未被破坏。示例:

>> nm my_class.so | grep hello
0000000000000935 T hello_world

而您的 python 代码将需要一个左括号来告诉它执行函数:

import ctypes

my_class = ctypes.cdll.LoadLibrary('./my_class.so')
my_class.hello_world()