使用SWIG在Python中封装C++类

10 投票
3 回答
15805 浏览
提问于 2025-04-16 09:23

example.h:

#ifndef EXAMPLE_H
#define EXAMPLE_H

class Math {
 public:
    int pi() const;
    void pi(int pi);
 private:
    int _pi;
};

#endif

example.cpp:

#include "example.h"

int Math::pi() const {
    return this->_pi;
}  
void Math::pi(int pi) {
    this->_pi = pi;
}

example.swig:

%module example
%{ 
    #define SWIG_FILE_WITH_INIT
    #include "example.h"
%}
%include "example.h"

然后我使用以下命令生成了包装器,"example.py" 和 "example_wrap.c":

swig  -python example.swig

当我尝试用以下命令编译包装类时:

g++ -fPIC -c example.cpp example_wrap.c -I/usr/local/include/python2.6/

我遇到了以下错误:

example_wrap.cpp: In function "PyObject* Swig_var_Math_get()":
example_wrap.cpp:2725: error: expected primary-expression before "void"
example_wrap.cpp:2725: error: expected ")" before "void"

错误出现在以下这一行:

pyobj = SWIG_NewPointerObj(SWIG_as_voidptr(&Math), SWIGTYPE_p_class,  0 );

#define SWIG_as_voidptr(a) (void *)((const void *)(a))

生成包装类 "example_wrap.c" 的方法是对的吗?

3 个回答

1

谢谢你的回复!

-c++这个选项更好,因为它可以生成实际的C++类,用于包装器(-v表示详细模式):

swig -c++ -v -python example.swig

然后我使用g++来编译这个包装器:

g++ -fPIC -c example.cpp example_wrap.cxx -I/usr/local/include/python2.6/

接着用下面的命令来构建共享对象。当然,你可能需要去掉一些多余的包含文件(-I)和库(-L)。重要的选项是-shared-fPIC

g++ example_wrap.o example.o -L/u01/app/oracle/product/1020.full/lib  -I/usr/local/ssl/include  -L/usr/local/ssl/lib -lclntsh -lssl -lcrypto -ldl -L/usr/local/lib -L/lib64 -L/usr/local/lib/python2.6/ -lboost_system -lboost_filesystem -lboost_thread -lboost_date_time -lglog -lmodpbase64 -lpthread -ldl -lrt -shared -fPIC -o _example.so
5

这里的信息不够多,无法确定问题出在哪里,不过我有两个建议可以试试。

  1. 你用的 g++ 命令把一个 C 源文件当成 C++ 来编译。这种做法 不一定 能成功。你可以试试这样:

    gcc -I/usr/local/include/python2.6 -fPIC -c example_wrap.c
    gcc -I/usr/local/include/python2.6 -fPIC -c example.cpp
    g++ -shared example_wrap.o example.o -o example.so
    

    (没错,真的,g++ 只用来链接)

  2. 如果这样还不行,可以这样编译 example_wrap.c

    gcc -I/usr/local/include/python2.6 -fPIC -c -save-temps example_wrap.c
    

这样做会以同样的方式失败,但会生成一个名为 example_wrap.i 的文件,这个文件是预处理的结果。它会非常大。你可以在这个文件里搜索函数 Swig_var_Math_get,然后把这个函数的 完整内容 加到你的问题里(其他的就不用了)。

13

我觉得正确的命令应该是“swig -c++ -python example.swig”。

撰写回答