gpt4 book ai didi

python - 如何使用 SWIG 接口(interface)访问 python 中的 C++ typedef 结构

转载 作者:太空宇宙 更新时间:2023-11-04 12:31:04 25 4
gpt4 key购买 nike

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

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

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

我在我的头文件中测试了以下结构,通过 SWIG 接口(interface)可用的对象是 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 添加到我的 .i 文件中,但仍然无法访问 TestTypedef:

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

typedef Test TestTypedef;
%include "MyHeader.h"

最佳答案

作为一般规则,SWIG 会尝试在目标语言中尽可能接近地反射(reflect) C 的行为。有时,当没有将 typedef 语义的一般情况映射到许多 SWIG 目标语言时,这会有点棘手。尽管在这个特定的实例中,您仍然可以使用两个可能的选项之一在 Python 中实现您正在寻找的行为。为了简化事情,尽管您希望在 header 中更加一致,所以要么总是对 TestN 结构进行类型定义,要么从不对它们进行类型定义。

首先,您可以在 %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 生成我们想要的接口(interface),并且它都是合法的、正确的、可编译的 C++ 代码。但是,如果我们对 SWIG 撒谎我们的 C++ 代码到底是什么样子,这并不重要。所以在实践中,如果我们声称我们的每个 typedef 实际上是一个派生类,但实际上它们只是 typedef,那么我们仍然会从中得到一个完美的工作接口(interface)。作为奖励,目标语言中的内容大多会更加类型安全,这可能很好:

%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

关于python - 如何使用 SWIG 接口(interface)访问 python 中的 C++ typedef 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58632303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com