views:

649

answers:

4

Hi All,

I am implementing a piece of Java software that will hopefully allow for C libraries as plugins. In order to call these future functions I need to somehow create a native function in Java from which I can call the code that doesn't exist yet.

The method signature will be static but the method and class names may change.

I am fairly new to C, ok very new to C, but I was wondering if there was a way to check the loaded libraries or available functions.

The way I would hope it to work would be as follows;

In my Java class I would have a function;

public static native void thirdParty(String class, String method, int[] data, int[] params);

Which would call a function in my C library;

JNIEXPORT void JNICALL Java_com_ex_app_Native_thirdParty(JNIEnv *, jclass, jstring, jstring, jintArray, jintArray);

From which I could take the class and method name and call them if they exist and throw an exception if not.

I guess what I'm looking for is some kind of Java style reflection but in C or failing that C++.

Any better ideas to achieve this goal would also be more than welcome!

Kind regards,

Gavin

+2  A: 

C and C++ don't really have Java-style reflection (though sometimes you can play tricks with looking up symbols in a shared library).

A more typical approach is to create a plugin interface in Java. Then for each external library, you write a (hopefully) small amount of custom Java and/or JNI code to translate plugin interface calls to calls to the backend library.

Mr Fooz
Does this approach require new java code for each plugin? Each plugin provides a method with the same parameters but performs a different calculation.The java code will be fixed after installation and I want to support different C plugin libraries.Sorry If this is the question you already answered, I just wanted to clarify.
gav
For each new C plugin, there would need to be a small amount of accompanying new Java code that translates the Java calls to the C calls. This approach assumes that you don't have control over the C libraries (Martin York's answer is the best if you do control the C libraries). I haven't used JNA, but Matthew Flaschen's suggestion looks like it might be an alternative to my suggestion when you don't control the C code.
Mr Fooz
A: 

The method signature will be static but the method and class names may change.

In C++ the method name and the class name are what determine what function you're calling, and are used to create the symbol JNI looks for (this is called name mangling).

There is hope. The plugin systems I'm familiar with require that each plugin implement a C function with a particular name and signature (in C++ you must mark this function as extern "C"), that will call whatever other functions and libraries needed, and the plugin system keeps track of which DLLs (Windows)/SOs (UNIX) belong to which plugin, and call the magic function from the corresponding file.

Since JNI requires a file and a function name, this is a straightforward way to implement your plugin system.

Max Lybbert
+2  A: 

The standard way (or common since there is no real standard)

Is to create a DLL (shared lib).
That DLL has a "C" function with a a fixed name that returns a pointer to a factory object.
You can then use the factory to build objects.

Example:

DLL-> Wdigets1.dll      C function -> extern "C" Fac& getWidgetFactory();  
DLL-> BoilerWidget.dll  C function -> extern "C" Fac& getWidgetFactory();  
DLL-> RoundWidget.dll   C function -> extern "C" Fac& getWidgetFactory();

Thus whatever dll you load all you need to do is get a pointer to the function getWidgetFactory() and now you can use the factory to build the appropriate widgets.

The reason behind this:
The libraries that allow you to load libraries dynamically also allow you to find methods/function by name. But the name you need to use is the full name. In "C" this is well defined. In "C++" this is the mangeled name and varies across compilers/platforms etc. So portable code can only find "C" names.

Martin York
+1  A: 

This sounds a lot like JNA, which basically allows you to lookup and call native functions from Java without writing custom JNI code. It uses the libffi foreign function library.

Matthew Flaschen