0

所以我想做的事情相当简单,我想使用 swig 在 Python 中访问一个 C++ 类。我已经设法为独立应用程序做到这一点,但这还不够。

我所拥有的:一个相当庞大的 C++ 库,它使用 SCons 编译。这会生成一个静态 (lib---.a) 库。我还有一个使用一些库功能的小型 C++ 类。

我试图做的是让 SCons 编译所有内容,包括我的自定义类,然后执行 swig 魔术。我定义了一个 swig 接口文件,包括我的头文件的结构,我也包含在 swig 接口文件中。

在头文件中有对库的依赖,但由于这些已经被编译(到静态库中),swig 找不到它。更换 SCons 不是一种选择。但是,我可以制作一个动态库而不是静态库。

所以我的问题归结为:是否有在 SCons 中使用 Swig 的正确方法,或者,您能否以某种方式将库依赖项包含为现有动态库?此外,我可以(使用 SCons)将我的自定义类编译为对象 (.o) 文件或动态库 (.so)。关于动态库,这就是事情变得混乱的地方,因为这也是 swig 生成的(?),或者至少是由某人生成的。

这甚至有意义吗?我显然如履薄冰,不一定知道我在说什么。

下面是 c++ 头文件和 swig 接口,我排除了 c++ 源代码,因为它感觉多余。

我的头文件:

#include "../include/LogCabin/Client.h"
#include "../include/LogCabin/Debug.h"
#include "../include/LogCabin/Util.h"

class Ops{
private:
    void dumpTree(std::string);
    void dumpTreeLocal(std::string);
public:
    Ops(std::string, uint64_t, std::string);
   ~Ops();
    ...
    void makeLeader();
    void getLeader();
    int reconfigure(std::vector<std::string>);
};

我对应的swig接口文件:

%module Ops

%{
#include "Ops.h"
%}
%include "Ops.h"

class Ops{
public:
    Ops(std::string, uint64_t, std::string);
    ~Ops();
    ...
    void makeLeader();
    void getLeader();
};

使用的命令:

swig -c++ -python Ops.i;
g++ -std=c++11 -c -fPIC Ops_wrap.cxx  -I/usr/include/python2.7 -I/usr/lib/python2.7;
g++ -std=c++11 -shared -Wl,-soname,_Ops.so -o _Ops.so Ops.o Ops_wrap.o;

谢谢。#swig

编辑:

我包括由 SConstruct 调用的 SConscript。

Import('env', 'object_files')

libs = [ "pthread", "protobuf", "rt", "cryptopp" ]

src = [
    "Ops.cc",
    "Ops.i"
]
/*object_files['Impl'] = env.StaticObject(src)*/

env.Default([
    env.SharedLibrary("Ops", src,
            LIBS = libs)
])

编辑2:

我更新了 SContruct env 声明来为 swig 设置一些参数。

env = Environment(options = opts,
              SWIGFLAGS=['-c++','-python'],
              CPPPATH=["/usr/include/python2.7"]),
              LIBPATH=["/usr/lib/python2.7"]),
              SHLIBPREFIX="",
              tools = ['default', 'protoc', 'packaging'],
              ENV = os.environ)

编译生成的 Ops_wrap.cc 文件时,它给了我很多类型转换警告,但仍然完成编译,例如

build/Impl/Ops_wrap.cc:654:23: warning: conversion to ‘unsigned char’ from ‘int’ may alter its value [-Wconversion]
       uu = ((d - '0') << 4);

当尝试通过生成的 Ops.py 文件访问 Ops 类时,导入 Ops 时出现错误:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    import Ops
ImportError: /home/erneborg/Applications/coherent/logcabin/build/Impl/Ops.so: undefined symbol: _ZNK8LogCabin6Client4Tree6readExERKSs

未定义的符号对应于库“LogCabin::Client::Tree::readEx()”中的一个函数。想法?

4

0 回答 0