假设我在头文件A.h
中有两个类A.// A.h
class A {
public:
void foo();
};
和B在头文件B.h
中// B.h
class B : public A {
public:
void bar()
};
我想为B类生成一个Swig包装器。接口文件看起来像这样。
B.i
%{
#include "B.h"
%}
%include B.h
当运行swig时,它会退出并显示一条错误消息“一无所知”,这很清楚,因为B继承自A,因此swig必须知道A才能生成接口。让我们进一步假设在A.h中有一些东西swig解析器无法解析它会在看到那些东西时产生错误。我突然决定,我实际上不仅需要在界面中使用bar而不是foo。有没有办法告诉swig,它实际上并没有看A.h,因为我真的不需要B继承自A的东西?
答案 0 :(得分:3)
我把一个例子汇总在一起,只得到一个警告没有任何关于A的信息。扩展程序仍然可以正常构建并且可以在不知道A的bar()的情况下调用B的foo()。这是我为Windows生成Python扩展的示例:
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
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
#pragma once
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
class DLL_API A
{
public:
void foo();
};
#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();
};
#include <stdio.h>
#define DLL_EXPORTS
#include "a.h"
void A::foo()
{
printf("In A::foo()\n");
}
#include <stdio.h>
#define DLL_EXPORTS
#include "b.h"
void B::bar()
{
printf("In B::bar()\n");
}
%module b
%begin %{
#pragma warning(disable:4100 4127 4706)
%}
%{
#include "B.h"
%}
%include <windows.i>
%include "B.h"
_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
答案 1 :(得分:3)
您可以对基类使用%import。这让SWIG知道了类,但是不会生成包装器。来自SWIG 2.0 documentation:
如果未定义任何基类,SWIG仍会生成正确的类型 关系。例如,接受Foo *的函数将接受 任何来自Foo的对象,无论SWIG是否实际 包裹了Foo类。 如果你真的不想生成包装器 对于基类,但是你想要使警告静音 考虑使用%import指令来包含定义的文件 富。 %import只收集类型信息,但不生成 包装器。或者,您可以将Foo定义为空类 在SWIG界面中或使用警告抑制。