使用 SWIG for Java,我如何有选择地 swig 巨大的 C/C++ 头文件的某些部分?

Posted

技术标签:

【中文标题】使用 SWIG for Java,我如何有选择地 swig 巨大的 C/C++ 头文件的某些部分?【英文标题】:Using SWIG for Java, how can I selectively swig certain parts of a huge C/C++ header file? 【发布时间】:2015-08-21 17:32:00 【问题描述】:

我有一些需要使用的旧版 C/C++ 头文件。这些头文件很大,我不想痛饮所有的元素。是否可以仅痛饮该头文件的某些部分,如果可以,我将如何处理?

例如,这是一个名为 BigHeaderFile.h 的 C 头文件,带有枚举声明:

#ifndef __HEADER_GUARD__
#define __HEADER_GUARD__

typedef enum _MYSTATUS 
    OK, NG, NONE
 MYSTATUS;

typedef enum _NOTINTERESTED 
    AVAL, BVAL, CVAL
 NOTINTERESTED;

#endif __HEADER_GUARD__

以下是我的 swig 文件:

%module MyNativeClass
%include "enums.swg"
%javaconst(1);

%include "BigHeaderFile.h"

当我在上面运行 swig 时,它会生成两个 java 类 MYSTATUS 和 NOTINTERESTED。有没有办法告诉 swig 只为 MYSTATUS 生成 java 枚举?

【问题讨论】:

【参考方案1】:

您几乎肯定在寻找SWIG's advanced renaming 功能。

你可以开始解决这个问题:

%rename("$ignore") "";

使 SWIG 忽略头文件中的所有声明。完成后,您可以有选择地重新启用任何您认为合适的包装。

所以你的 .i 文件变成:

%module MyNativeClass
%include <enums.swg>
%javaconst(1);

%rename("$ignore") ""; // ignore all
%rename("%s") "MYSTATUS"; // except MYSTATUS

%include "BigHeaderFile.h"

除了简单的名称匹配之外,您还可以指定要取消忽略的内容,例如正则表达式、命名空间、类型(类/模板/枚举/常量/...)

事实证明,我上面的基本示例与an example in the docs 几乎相同。

【讨论】:

【参考方案2】:

我可以想到两种方法来做到这一点:

    制作文件 BigHeaderFile.h 的副本,将其重命名为 BigHeaderFile.i,删除不需要 swig 包装器的部分,并改为在 swig 文件 %include "BigHeaderFile.i" 中。

    在 swig 文件中包含文件 BigHeaderFile.h 之前,使用 %ignore NOTINTERESTED; 告诉 swig 忽略 NOTINTERESTED。然后 Swig 将不会为该类生成包装器。

请注意,无论哪种情况,您都可能需要添加

% 
#include "BigHeaderFile.h"
%

到您的 swig 文件的顶部,以便将这一行放入包装器代码中。否则,它不应该编译。

【讨论】:

以上是关于使用 SWIG for Java,我如何有选择地 swig 巨大的 C/C++ 头文件的某些部分?的主要内容,如果未能解决你的问题,请参考以下文章

如何定义 swig 类型映射以将 unsigned char* 返回到 java

在 Linux 中使用 SWIG for Python 转换字符串

将 SWIG 与 C++ 的 std::map 一起使用时,Java 没有迭代器

SWIG (Java):如何将带有回调函数的结构从 Android 应用程序传递给 C++?

带有指针的C结构,如何Swig?

SWIG - 如何忽略我不需要公开的 C++ 类(在 Java 中)?