views:

508

answers:

7

Has anyone successfully "wrapped up" a C++ API in Java or .NET? I have an application that provides a C++ API for writing plug-ins. What I'd like to do is access that API from .NET or Java.

Would I need to use COM, or are there simpler/better alternatives?

+1  A: 

On the Java side there are many options here .. this question actually is fairly close to what you are looking for provided your API can be boxed in a DLL, com or activex objects.

I personnaly used JIntegra to wrap API calls to office (Word) and used it directly witin Java. It did take some hacking to get the desired functionnality but we ended up making it work. The fidling was actually on the Word side, the actual integration was relatively easy.

Newtopian
+1  A: 

I think that you may be asking to something similar to the Java Native Inferface It allows you to call code written in languages such as C++. I've never worked with it though. But you may want to check it out. Hope it helps.

jasonco
+5  A: 

If you have a very straight forward method signatures (i.e. methods that takes and returns primitive types such as int, char[], void* ... etc), it is reasonably easy to do so in .NET and still possible but a bit harder in Java with JNI.

However, if your class methods uses modern C++ programming techniques such as boost shared pointers and STL containers then it is a very different story. You will need to be really careful with memory management in this case.

EDIT: It is gonna be even more interesting if the method has C++ template arguments because C++ template system is very different from C# or Java generics in that it is only a compile time mechanism. Basically this means the signature of the method or class is different every time you pass a different data type to the template argument. This made the method impossible to wrap in C# or Java.

oykuo
A: 

I'm the lead author on SlimDX. It may not be the largest open source interoperability project out there, but at 150K+ lines across the project, it's fairly substantial. It's written using C++/CLI, which is a Microsoft developed language, largely compatible with C++, that is designed to allow you to build wrappers. It works very well, with the caveat that it is Windows only. Mono will not take it. I don't know how much of a concern that is for you, but it's probably a better alternative than COM. Unfortunately there's a lot of tips and tricks that you have to basically come up with yourself. I've meant to blog about a lot of the ones we use on SlimDX, but somehow I never quite get around to it.

On the Java side, I believe you have to use JNI. Good luck with that. I've never talked to anyone who's worked with JNI without both of us laughing at it, in a bad "ouch that hurt" sort of way.

Promit
A: 

If you are going to use .NET, I would recommend creating a C++/CLI wrapper. C++/CLI lets you mix the managed .NET code with native C++ code. There are some tricks to this approach, but it works very well in majority of cases.

Wikipedia entry has also some good links.

Filip
+1  A: 

Using SWIG to handle the JNI stuff makes wrapping a cpp API and using it from Java quite painless.

Here's a SWIG tutorial

justinhj
A: 

I maintain software that is implemented in C++ but must have interfaces in multiple languages including Java and .NET, but also including delphi and VB6. Plus, it has to work on multiple platforms (so Java needs to work on unix).

The way it was done was to use a single DLL exporting plain C functions using primitive types. For example, given an class Foo:

long MY_EXPORT_FLAG FooCreate()
{
    return (long)new Foo();
}

void MY_EXPORT_FLAG FooDestroy(long Handle)
{
   delete (Foo*)Handle;
}

void MY_EXPORT_FLAG BarMethod(long Handle, const char* pStr1, long* pReturnValue)
{
   *pReturnValue = ((Foo*)Handle)->BarMethod( pStr1 );
}

Then your JNI/.NET/VB6/Delphi code implements language specific class wrappers, but call these C dll functions. Each class wrapper would contain a Handle, and pass it into the C functions.

This works quite well because most languages tend to use C as the lowest common denominator, so as long as you can export your interfaces through a thin C api you can build interfaces for other languages.

We export a C (and not C++) api in the DLL because function signatures are much more standardized across platforms.

Don't forget, that on C# and Java, you'll have to deal with multibyte string encoding, so you should figure out how to transcode your strings to/from your C++ code. This typically involves knowing about locales, or you can cheap out and just support UTF-8.

Snazzer