避免在Swig中出现“关于[父类]的任何信息...”错误

Chr*_*ian 5 swig interface wrapper

假设我在头文件Ah中有两个类A

// A.h
class A {
public:
  void foo();
};
Run Code Online (Sandbox Code Playgroud)

和B在头文件Bh中

// B.h
class B : public A {
public:
  void bar()
};
Run Code Online (Sandbox Code Playgroud)

我想为类B生成一个Swig包装器。接口文件如下所示。

B.i
%{
#include "B.h"
%}

%include B.h
Run Code Online (Sandbox Code Playgroud)

运行swig时,它退出并显示一条错误消息“ A无关”,这很清楚,因为B继承自A,因此swig必须知道A才能生成接口。让我们进一步假设swig解析器无法解析Ah中的某些内容,并且在看到该内容时会生成错误。我突然决定,实际上我不需要接口中的bar而不是foo。有没有办法告诉s,因为我真的不需要B从A继承来的东西,所以它实际上并没有看Ah。

Cod*_*key 5

您可以使用 %import 作为基类。这让 SWIG 了解该类,但不会生成包装器。来自SWIG 2.0 文档

如果任何基类未定义,SWIG 仍会生成正确的类型关系。例如,接受 Foo * 的函数将接受从 Foo 派生的任何对象,无论 SWIG 是否实际包装了 Foo 类。如果您确实不想为基类生成包装器,但希望消除警告,则可以考虑使用 %import 指令来包含定义 Foo 的文件。%import 只是收集类型信息,但不生成包装器。或者,您可以在 SWIG 接口中将 Foo 定义为空类或使用警告抑制。


Mar*_*nen 4

我拼凑了一个例子,只得到一个警告,表明对 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
Run Code Online (Sandbox Code Playgroud)

使用示例

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
Run Code Online (Sandbox Code Playgroud)

文件

#pragma once

#ifdef DLL_EXPORTS
    #define DLL_API __declspec(dllexport)
#else
    #define DLL_API __declspec(dllimport)
#endif

class DLL_API A
{
public:
    void foo();
};
Run Code Online (Sandbox Code Playgroud)

乙肝

#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();
};
Run Code Online (Sandbox Code Playgroud)

a.cpp

#include <stdio.h>
#define DLL_EXPORTS
#include "a.h"

void A::foo()
{
    printf("In A::foo()\n");
}
Run Code Online (Sandbox Code Playgroud)

b.cpp

#include <stdio.h>
#define DLL_EXPORTS
#include "b.h"

void B::bar()
{
    printf("In B::bar()\n");
}
Run Code Online (Sandbox Code Playgroud)

%module b

%begin %{
#pragma warning(disable:4100 4127 4706)
%}

%{
#include "B.h"
%}

%include <windows.i>
%include "B.h"
Run Code Online (Sandbox Code Playgroud)

生成文件

_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
Run Code Online (Sandbox Code Playgroud)