如何使用SWIG接口在python中访问C ++ typedef的结构

问题描述 投票:1回答:1

我正在尝试配置我的SWIG接口以公开所有定义的typedef。

示例:对于我的C ++头文件中的以下内容,我希望我的python代码能够创建对象A,B,C,D,E。

//MyHeader.h
struct Common
{
    uint8_t     eId;
};
typedef Common A, B, C, D, E;

我已经在头文件中对以下结构进行了测试,并且通过SWIG接口可用的对象是Test,Test2Typedef和Test3Typedef1,但没有测试类型,Test2,Test3或Test3Typedef2。

//MyHeader.h
struct Test {
    uint8_t uValue;
};
typedef Test TestTypedef;

typedef struct Test2 {
    uint8_t uValue;
} Test2Typedef;

typedef struct Test3 {
    uint8_t uValue;
} Test3Typedef1, Test3Typedef2;

我已经尝试将以下typedef添加到我的.i文件中,但仍然无法访问TestTypedef:

//MyHeader.i
%{
#include "MyHeader.h"
typedef Test TestTypedef;
%}

typedef Test TestTypedef;
%include "MyHeader.h"
python c++ swig
1个回答
0
投票

作为一般规则,SWIG试图在目标语言中尽可能接近地反映C的行为。有时,如果没有将typedef语义映射到SWIG目标语言中的许多情况下,这有点棘手。尽管在此特定情况下,您仍然可以使用两个可能的选项之一来实现您在Python中寻找的行为。为简化起见,尽管您希望头文件中的内容更加一致,所以请始终对TestN结构进行typedef定义,或从不对它们进行typedef。

首先,您可以在%pythoncode内编写一些额外的Python代码,以确保Python中每种类型都有一个与您期望的匹配的别名。以下界面显示:

%module test


%inline %{

struct Test {
    uint8_t uValue;
};
typedef Test TestTypedef;

struct Test2 {
    uint8_t uValue;
};
typedef Test2 Test2Typedef;

struct Test3 {
    uint8_t uValue;
};
 typedef Test3 Test3Typedef1, Test3Typedef2;

%}

%pythoncode %{
  TestTypedef = Test
  Test2Typedef = Test2
  Test3Typedef1 = Test3
  Test3Typedef2 = Test3
%}

但是,替代方法是在C ++层中进行一些欺骗。实际上,我们要做的就是确保SWIG生成所需的接口,并且该接口都是合法,正确,可编译的C ++代码。但是,无论我们是否对SWIG说谎,我们的C ++代码到底是什么都没关系。因此,在实践中,如果我们声称每个typedef实际上是派生类,但实际上它们只是typedef,那么我们仍然会从中获得一个完美的接口。另外,在目标语言中,多数情况下类型更安全,这可能很好:

%module test


%{
// This is what the C++ compiler sees:    
struct Test {
    uint8_t uValue;
};
typedef Test TestTypedef;

struct Test2 {
    uint8_t uValue;
};
typedef Test2 Test2Typedef;

struct Test3 {
    uint8_t uValue;
};
typedef Test3 Test3Typedef1, Test3Typedef2;

%}

// This is the lie we tell SWIG, but it's compatible with what the C++ code really is doing
struct Test {
    uint8_t uValue;
};

struct Test2 {
    uint8_t uValue;
};

struct Test3 {
    uint8_t uValue;
};

struct Test2Typedef : Test2 {};
struct Test3Typedef1 : Test3 {};
struct Test3Typedef2 : Test3 {};

这些都让我们运行此Python代码:

import test

a = test.Test3Typedef2()

如果是我这样做,我将为typedef生成定义一个宏:

#ifndef SWIG
#define MAKE_TYPEDEF(original, renamed) typedef original renamed
#else
#define MAKE_TYPEDEF(original, renamed) struct renamed : original {}
#endif 

然后可以将其保存在头文件中,并允许您仍然使用%include

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.