Search code examples
c++creflectionjava-native-interface

C/C++ Reflection and JNI - A method for invoking native code which hasn't been written yet


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.

Is there a way to check the loaded libraries or available functions? The way I hope it would 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 they don't.

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

How can I achieve this?


Solution

  • 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.