簡體   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