2

The issue is fairly simple, I have some constants in a C++ namespace that I would like to wrap using SWIG 2.0.8. It looks something like this:

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

Unfortunately SWIG handles this rather awkwardly. In the C# case, it adds the constants to a class with the same name as the namespace so it must be accessed by using Example.Example.PI even when I am explicitly using Example (due to masking by the module name).

In Java, its even worse as it does not treat it as a constant at all and I am forced to call it using Example.getPI() as a method call instead of a constant class variable.

If I move the constants to the global namespace, this seems to work but then the variables must be accessed using ExampleConstants.PI.

Ideally, I would like both languages to be able to access the constants via Example.PI to be consistent with C++. But a compromise that I would be happy with is if I could have a Constants class inside my namespace so that I can use Constants.PI in either language. But of course, C++ does not allow non-integral types to be defined inside a class and this is still not solving the issue in Java.

Is there any elegant way to handle these namespace constants with SWIG? And if not, is there a way I can manually add a Java or C# class to define them?

KevinH
  • 413
  • 2
  • 7
  • `Example.PI` is not the way to access the variable in C++. You would need `Example::PI`. – juanchopanza Dec 17 '12 at 06:38
  • Yes I realize that, but the . is how you use the :: in the other languages. – KevinH Dec 17 '12 at 06:40
  • Well, you say you want to be consistent with C++ and then you show something that is not legal C++, so your requirements are not very clear. – juanchopanza Dec 17 '12 at 06:41
  • Sorry if I wasn't clear. By consistent, I mean as close as possible given the restrictions and syntax of the target languages. – KevinH Dec 17 '12 at 06:43

1 Answers1

2

I solved similar problem for C++ - C#. I am not sure if this is exactly what you are looking for, but I hope you will find some info useful for you.

I have not touched Java code in my project.

Swig solution.

I created class with public static parameterless functions in C++.

Then I exported them to C# using SWIG.
I specified namespace for C# in command line with -namespace <name> key. More details available at page SWIG and C#

As a result you can impelement solution to access your constant with Constants::PI() and Constants.PI()

Direct solution

If you would like not to use SWIG or other library, you should use PInvoke. There are a lot details and special cases when working with it. Most comprehensive article on subject I have found is Mono Interop with Native Libraries

You should consider JNI for Java.

Note, that C++ functions are exported without namespaces as pure C functions and you should create C# class and create functions with DllImport attribute to wrap functions back to namespaces.

In general if your C++ interface is more or less fixed and/or small I would adhere direct solution, because SWIG layer has many-many specific cases which should be learned along with PInvoke/JNI. But if you C++ interface frequently changed and requires a lot of effort to keep C++, C# and Java consistent, you defenitely need to consider SWIG.

You may find non-trivial example using PInvoke at https://stackoverflow.com/a/11909571/13441

Concerning C++ constants. You can specify C++ constant inside class, refer to C++ static constant string (class member) for details.

I use SWIG 1.3.40.

Hope this is helpful.

Community
  • 1
  • 1
sergtk
  • 10,714
  • 15
  • 75
  • 130