避免“对[父]类一无所知......”喝水时出错

发布于 2024-10-08 04:46:42 字数 512 浏览 0 评论 0原文

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

// A.h
class A {
public:
  void foo();
};

,在头文件 Bh 中有两个类 B,

// B.h
class B : public A {
public:
  void bar()
};

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

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

%include B.h

运行 swig 时,它会退出并显示错误消息“对 A 一无所知”,这很清楚,因为 B 继承自 A,因此 swig 必须了解 A 才能生成接口。让我们进一步假设 Ah 中有一些东西,swig 解析器无法解析,并且当它看到这些东西时会生成错误。我突然决定,我实际上不仅需要界面中的 bar,而且不需要 foo。有没有一种方法可以告诉 swig,它实际上并不看 Ah,因为我真的不需要 B 从 A 继承的东西?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烂柯人 2024-10-15 04:46:42

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

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

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.

霊感 2024-10-15 04:46:42

我拼凑了一个例子,只得到一个警告,表明对 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

文件

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文