swig命名空间错误?不是有效的基类

时间:2013-04-03 04:27:00

标签: java c++ swig

我使用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

有什么想法吗?

2 个答案:

答案 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):

demo.i

%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"

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)
相关问题