繁体   English   中英

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

[英]How to access C++ typedef'd structures in python with SWIG interface

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

Example: For the following in my C++ header file I want my python code to be able to create objects A, B, C, D, E.

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

我在 header 文件中使用以下结构进行了测试,通过 SWIG 接口可用的对象是 Test、Test2Typedef 和 Test3Typedef1,但不是 TestTypedef、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 添加到 my.i 文件中,但仍然无法访问 TestTypedef:

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

typedef Test TestTypedef;
%include "MyHeader.h"

作为一般规则,SWIG 尝试在目标语言中尽可能接近地反映 C 的行为。 有时这有点棘手,尽管没有将 typedef 语义映射到许多 SWIG 目标语言的一般情况下。 在这个特定的例子中,尽管您仍然可以使用两个可能的选项之一来实现您在 Python 中寻找的行为。 为了简化事情,尽管您希望在 header 中更加一致,所以要么总是 typedef TestN结构,要么永远不要 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 实际上是派生的 class,但实际上它们只是 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 

然后它可以存在于 header 文件中,并且允许您仍然使用%include

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM