我使用SWIG来包装C ++库。我收到一个错误,我认为这与我使用命名空间有关,但我不确定。不幸的是,SWIG的文档似乎都集中在内联文档上,我不知道它是从头文件中提取的内容。
这是我的.i文件:
%module cStopPow
%{
#include "../src/StopPow.h"
#include "../src/StopPow_SRIM.h"
#include "../src/StopPow_LP.h"
#include "../src/StopPow_BetheBloch.h"
%}
%include "cpointer.i"
%pointer_functions(int, intp);
%pointer_functions(float, floatp);
%include "std_vector.i"
#include <vector>
// Instantiate templates
namespace std {
%template(IntVector) vector<int>;
%template(FloatVector) vector<float>;
}
%include "std_string.i"
#include <string>
%include "../src/StopPow.h"
%include "../src/StopPow_SRIM.h"
%include "../src/StopPow_LP.h"
%include "../src/StopPow_BetheBloch.h"
这是一个裁剪的示例标题(它们都非常类似地定义):
#include ...
namespace StopPow
{
class StopPow_BetheBloch : StopPow
{ ...
其中三个类延伸了StopPow。库在C ++下编译得很好但是SWIG给了我以下错误:
swig -java -c++ StopPow.i
../src/StopPow_BetheBloch.h:26: Warning 319: No access specifier given for base class 'StopPow' (ignored).
../src/StopPow_SRIM.h:27: Error: 'StopPow' is not a valid base class.
../src/StopPow.h:28: Error: See definition of 'StopPow'.
../src/StopPow_SRIM.h:27: Warning 401: Nothing known about base class 'StopPow'. Ignored.
../src/StopPow_LP.h:27: Error: 'StopPow' is not a valid base class.
../src/StopPow.h:28: Error: See definition of 'StopPow'.
../src/StopPow_LP.h:27: Warning 401: Nothing known about base class 'StopPow'. Ignored.
../src/StopPow_BetheBloch.h:26: Error: 'StopPow' is not a valid base class.
../src/StopPow.h:28: Error: See definition of 'StopPow'.
make: *** [StopPow] Error 6
有什么想法吗?
答案 0 :(得分:0)
好的,经过多次故障排除后,我发现了这一点。在将我的代码放入非std命名空间后出现这些问题,上面的.i文件在我的所有代码都在std时都有效。
有两个问题。首先,必须在.i文件显式中定义基类,这在文档中提到并且我错过了。此外,显然SWIG不支持定义了构造函数的基类。将一个方法StopPow()添加到StopPow类会导致“错误:'StopPow'不是从它继承的三个类的有效基类。”
这是工作StopPow.i:
// StopPow.i - SWIG interface
%module cStopPow
%{
#include "../src/StopPow.h"
#include "../src/StopPow_SRIM.h"
#include "../src/StopPow_LP.h"
#include "../src/StopPow_BetheBloch.h"
%}
%include "cpointer.i"
%pointer_functions(int, intp);
%pointer_functions(float, floatp);
%include "std_vector.i"
#include <vector>
// Instantiate templates
namespace std {
%template(IntVector) vector<int>;
%template(FloatVector) vector<float>;
}
%include "std_string.i"
#include <string>
//%nspace StopPow::StopPow;
//%nspace StopPow::StopPow_LP;
// Need to define the base class:
namespace StopPow
{
class StopPow {
public:
//StopPow();
virtual float dEdx_MeV_um(float E) = 0;
virtual float dEdx_MeV_mgcm2(float E) = 0;
virtual float get_Emin() = 0;
virtual float get_Emax() = 0;
float dEdx(float E);
float Eout(float E, float x);
float Ein(float E, float x);
float Thickness(float E1, float E2);
float get_dx();
void set_dx(float new_dx);
int get_mode();
void set_mode(int new_mode);
static const float DEFAULT_DX;
static const float DEFAULT_DRHOR;
static const int MODE_LENGTH;
static const int MODE_RHOR;
};
};
%include "../src/StopPow_SRIM.h"
%include "../src/StopPow_LP.h"
%include "../src/StopPow_BetheBloch.h"
答案 1 :(得分:0)
SWIG处理带有构造函数/析构函数的基类就好了。问题是拥有一个与类同名的命名空间。示例(对于Python):
%module demo
%begin %{
#pragma warning(disable:4127 4100 4211 4701 4706)
%}
%{
#include "demo.h"
%}
%include <std_vector.i>
%include <std_string.i>
%template(IntVector) std::vector<int>;
%include "demo.h"
#include <iostream>
#include <string>
#include <vector>
namespace C {
class A {
public:
A() { std::cout << __FUNCSIG__ << std::endl; }
virtual std::vector<int> func(int a, int b) { return std::vector<int>(a,b); }
std::string func2() { return std::string("From A"); }
virtual ~A() { std::cout << __FUNCSIG__ << std::endl; }
};
class B : public A {
public:
B() { std::cout << __FUNCSIG__ << std::endl; }
std::vector<int> func(int a, int b) { return std::vector<int>(b,a); }
std::string func3() { return std::string("From B"); }
~B() { std::cout << __FUNCSIG__ << std::endl; }
};
}
构建和运行在SWIG代码生成期间显示错误,但仍然可以成功编译。
结果有两个问题:
B
实例不了解基类A
。B
实例在删除时不会调用其析构函数。输出:
C:\>swig -c++ -python demo.i
demo.h(13) : Error: 'A' is not a valid base class.
demo.h(8) : Error: See definition of 'A'.
demo.h(13) : Warning 401: Nothing known about base class 'A'. Ignored.
C:\>cl /EHsc /LD /W4 /MD demo_wrap.cxx /I%PYTHON_ROOT%\include /nologo -link /nologo /LIBPATH:%PYTHON_ROOT%\libs /OUT:_demo.pyd
demo_wrap.cxx
Creating library demo_wrap.lib and object demo_wrap.exp
C:\>py -3
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import demo
>>> a=demo.A()
__cdecl A::A::A(void)
>>> a.func(3,4)
(4, 4, 4)
>>> a.func2()
'From A'
>>> b=demo.B()
__cdecl A::A::A(void)
__cdecl A::B::B(void)
>>> b.func(3,4)
(3, 3, 3, 3)
>>> b.func2()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".\demo.py", line 167, in <lambda>
__getattr__ = lambda self, name: _swig_getattr(self, B, name)
File ".\demo.py", line 55, in _swig_getattr
raise AttributeError(name)
AttributeError: func2
>>> b.func3()
'From B'
>>> del a
__cdecl A::A::~A(void)
>>> del b
>>>
命名空间更改为C
后的输出:
C:\>swig -c++ -python demo.i
C:\>cl /EHsc /LD /W4 /MD demo_wrap.cxx /I%PYTHON_ROOT%\include /nologo -link /nologo /LIBPATH:%PYTHON_ROOT%\libs /OUT:_demo.pyd
demo_wrap.cxx
Creating library demo_wrap.lib and object demo_wrap.exp
C:\>py -3
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import demo
>>> a=demo.A()
__cdecl C::A::A(void)
>>> a.func(3,4)
(4, 4, 4)
>>> a.func2()
'From A'
>>> b=demo.B()
__cdecl C::A::A(void)
__cdecl C::B::B(void)
>>> b.func(3,4)
(3, 3, 3, 3)
>>> b.func2()
'From A'
>>> b.func3()
'From B'
>>> del a
__cdecl C::A::~A(void)
>>> del b
__cdecl C::B::~B(void)
__cdecl C::A::~A(void)