Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 wrapper 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?

like image 725
Christian Avatar asked Dec 19 '10 15:12

Christian


1 Answers

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
like image 84
Mark Tolonen Avatar answered Oct 10 '22 20:10

Mark Tolonen