SWIG中的命名空间常量

时间:2012-12-17 06:35:58

标签: c# java c++ swig

问题很简单,我在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#类来定义它们?

1 个答案:

答案 0 :(得分:2)

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

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

Swig解决方案。

我在C ++中使用公共静态无参数函数创建了类。

然后我使用SWIG将它们导出到C# 我在命令行中使用-namespace <name>键为C#指定了命名空间。有关详情,请参阅第SWIG and C#

因此,您可以通过Constants::PI()Constants.PI()

来访问常量

直接解决方案

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

您应该考虑使用JNI来获取Java。

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

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

您可以在https://stackoverflow.com/a/11909571/13441

处找到使用PInvoke的非平凡示例

关于C ++常量。您可以在类中指定C ++常量,有关详细信息,请参阅C++ static constant string (class member)

我使用SWIG 1.3.40。

希望这有用。