Avoid 'nothing known about [parent] class...' error in swig
Let's say I have two classes A in header file A.h
// A.h
class A {
public:
void foo();
};
and B in header file B.h
// B.h
class B : public A {
public:
void bar()
};
I want to generate a Swig w开发者_运维技巧rapper for class B. The interface file looks like this.
B.i
%{
#include "B.h"
%}
%include B.h
When running swig, it quits with an error message 'nothing known about A', which is clear, since B inherits from A and thus swig must know about A to generate the interface. Lets further assume there is some stuff in A.h the swig parser can not parse and it generates an error, when it sees that stuff. I suddenly decide, that I actually don't only need bar in the interface and not foo. Is there A way to tell swig, that it doesn't actually look at A.h, since I don't really need the stuff B inherits from A?
I threw together an example, and only get a warning that nothing is known about A. The extension still builds fine and can call B's foo() without knowing about A's bar(). Here's my example generating a Python extension for Windows:
Build output
C:\example>nmake /las
b.cpp
a.cpp
Generating Code...
Creating library b.lib and object b.exp
B.h(12) : Warning 401: Nothing known about base class 'A'. Ignored.
b_wrap.cxx
Creating library _b.lib and object _b.exp
Example use
Python 2.6.6 (r266:84297, Aug 24 2010, 18:46:32) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import b
>>> b.B().bar()
In B::bar()
>>> b.B().foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "b.py", line 73, in <lambda>
__getattr__ = lambda self, name: _swig_getattr(self, B, name)
File "b.py", line 54, in _swig_getattr
raise AttributeError(name)
AttributeError: foo
Files
a.h
#pragma once
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
class DLL_API A
{
public:
void foo();
};
b.h
#pragma once
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
#include "a.h"
class DLL_API B : public A
{
public:
void bar();
};
a.cpp
#include <stdio.h>
#define DLL_EXPORTS
#include "a.h"
void A::foo()
{
printf("In A::foo()\n");
}
b.cpp
#include <stdio.h>
#define DLL_EXPORTS
#include "b.h"
void B::bar()
{
printf("In B::bar()\n");
}
b.i
%module b
%begin %{
#pragma warning(disable:4100 4127 4706)
%}
%{
#include "B.h"
%}
%include <windows.i>
%include "B.h"
makefile
_b.pyd: b.dll b_wrap.cxx
cl /nologo /EHsc /LD /W4 b_wrap.cxx /I c:\Python26\include /Fe_b.pyd -link /nologo /libpath:c:\Python26\libs b.lib
b_wrap.cxx: b.i
swig -c++ -python b.i
b.dll: a.cpp b.cpp
cl /nologo /LD /W4 b.cpp a.cpp
You could use %import for the base class. This lets SWIG know about the class, but no wrappers will be generated. From the SWIG 2.0 documentation:
If any base class is undefined, SWIG still generates correct type relationships. For instance, a function accepting a Foo * will accept any object derived from Foo regardless of whether or not SWIG actually wrapped the Foo class. If you really don't want to generate wrappers for the base class, but you want to silence the warning, you might consider using the %import directive to include the file that defines Foo. %import simply gathers type information, but doesn't generate wrappers. Alternatively, you could just define Foo as an empty class in the SWIG interface or use warning suppression.
精彩评论