2

问题很简单,我在 C++ 命名空间中有一些常量,我想使用 SWIG 2.0.8 进行包装。它看起来像这样:

namespace Example {
    static const float PI = 3.14159f
    ...
    /* Lots of classes are here */
}

不幸的是,SWIG 相当笨拙地处理了这个问题。在 C# 的情况下,它将常量添加到与命名空间同名的类中,因此Example.Example.PI即使我显式地使用它也必须使用它来访问它using Example(由于模块名称的屏蔽)。

在 Java 中,它甚至更糟,因为它根本不将其视为常量,我被迫使用Example.getPI()方法调用而不是常量类变量来调用它。

如果我将常量移动到全局命名空间,这似乎可行,但必须使用ExampleConstants.PI.

理想情况下,我希望两种语言都能够通过Example.PI与 C++ 保持一致来访问常量。但是我会满意的一个折衷方案是,如果我可以Constants在我的命名空间中有一个类,以便我可以Constants.PI在任何一种语言中使用。但是当然,C++ 不允许在类中定义非整数类型,这仍然不能解决 Java 中的问题。

有没有什么优雅的方法可以用 SWIG 处理这些命名空间常量?如果没有,有没有办法可以手动添加 Java 或 C# 类来定义它们?

4

1 回答 1

2

我为 C++ - C# 解决了类似的问题。我不确定这是否正是您正在寻找的,但我希望您能找到一些对您有用的信息。

我的项目中没有接触过 Java 代码。

痛饮解决方案。

我在 C++ 中创建了具有公共静态无参数函数的类。

然后我使用 SWIG 将它们导出到 C#。
我在命令行中用-namespace <name>键为 C# 指定了命名空间。更多详细信息可在SWIG 和 C#页上找到

Constants::PI()因此,您可以使用和访问常量的解决方案Constants.PI()

直接解决方案

如果您不想使用 SWIG 或其他库,则应使用PInvoke。使用它时有很多细节和特殊情况。我发现的关于该主题的最全面的文章是Mono Interop with Native Libraries

您应该考虑使用JNI for Java。

请注意,C++ 函数在没有命名空间的情况下作为纯 C 函数导出,您应该创建 C# 类并创建具有DllImport 属性的函数以将函数包装回命名空间。

一般来说,如果您的 C++ 接口或多或少是固定的和/或较小的,我会坚持直接解决方案,因为 SWIG 层有许多特定情况,应该与 PInvoke/JNI 一起学习。但是,如果您的 C++ 接口经常更改并且需要大量努力来保持 C++、C# 和 Java 的一致,那么您肯定需要考虑 SWIG。

您可以在https://stackoverflow.com/a/11909571/13441找到使用 PInvoke 的重要示例

关于 C++ 常量。您可以在类中指定 C++ 常量,详情请参阅C++ 静态常量字符串(类成员)

我使用 SWIG 1.3.40。

希望这会有所帮助。

于 2012-12-30T02:04:17.127 回答