Search code examples
javaandroidcandroid-ndkjava-native-interface

Using existing C code files to build in Android and pass information from my java code to the C code


I understand that I need to look at using NDK and JNI to integrate C and Java, however all the tutorials seem to point at writing your own C code. I have been given a huge directory which includes .c files and corresponding .h files. I am told this C code has been produced by MatLab. Please bear in mind that I am a Java developer and my C knowledge is not great. Within this directory are 2 .mk files and a few other file types as well (.bat, .rsp, etc.), in total about 360 files. I need to build this implementation, be able to pass information to a few functions and receive information back as well.

What is the process I need to follow to achieve this? Because the information online speaks about creating header files etc.. however the header files in C already exist. I think my most important question is how do I integrate this and build it so I can then use JNI to interact with the C code?

The C application simply takes my inputs and does some maths and provides me an out put object with the data I require.


Solution

  • Your strategy would be the following:

    1. Create Android project with native C/C++ code support, e.g. like here: https://developer.android.com/studio/projects/add-native-code. And your goal is to create the following chain:

      [Your Android Java app] --> [JNI Java API] --> [JNI native] --> [MatLab native]
      

      JNI is just to marshal a Java call to a targeted MatLab function.

    2. Generate a C code only for a Matlab function that you really need. Check documentation (https://www.mathworks.com/help/dsp/ug/generate-c-code-from-matlab-code-1.html):

      You do not have to generate code for the entire MATLAB application. If you have specific portions that are computationally intensive, generate code from these portions in order to speed up your algorithm. Make Code Suitable for Code Generation

    3. Generate JNI with methods designed by yourself: e.g. you will have MatLabJniApi.java (JNI Java API) and you will get com_your_MatLabJniApi.c (and com_your_MatLabJniApi.h) as a result of javac -h . MatLabJniApi.java command (JNI native implementation).

    4. Finally, call MatLab function from generated JNI native C/C++ files:

      #include <matlab_header_with_foobar.h>
      ...
      JNIEXPORT void JNICALL Java_com_your_MatLabJniApi_foobar (JNIEnv* env, jobject thisObject) {
         ...
         foobar_from_matlab();
         ...
      }
      

      Keep JNI clear and minimal: it is just a bridge to the code produced by MatLab.

    5. Put all C/C++ files into a single folder (cpp/ or jni/, depending on your Android project structure), so they will compile together by cmake (or by ndk-build, depending on a chosen method to compile a JNI).

    Good luck!

    P.S.: example of Android.mk

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE := mymatlab         # Name of your module
    LOCAL_SRC_FILES := 1.c 2.c 3.c   # Sources, and here you can try $(wildcard *.c)
    include $(BUILD_STATIC_LIBRARY)  # This means to build libmymatlab.a