1

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.

8
  • The C functions you wish to call from Java must be named in a specific manner (unless you use RegisterNatives). There are tools in the JDK that can create headers with correctly named C function declarations based on the native method declarations in your Java code. And then it's up to you to write the C function definitions. Or you might look into using something like SWIG, which does some of this for you, but on the other hand you then need to learn how to use SWIG. Commented Apr 24, 2020 at 11:44
  • @Michael Thanks for taking the time to help, What i take from that is that i need to have my methods in java declared as Native, i then use the tools to create new Header files. So i don't use the existing ones already in the C directory? Pardon my stupidity but why would i have to re-write the C functions again? an i writing out everything again? Do i not interact directly with the existing C code? Apologies if I'm confusing matters! Before this i need to create an Android.mk file to build the existing C code i have been given? I am reading a lot but making this use specific seems difficult. Commented Apr 24, 2020 at 12:35
  • Typically your existing C functions won't follow the JNI naming convention. So let's say that you have a C function named foo, and you have it declared as a native method in the Java class com.mycompany.MyClass. Then you'd write another C function named Java_com_mycompany_MyClass_foo which calls the actual foo function, and converts / passes along function arguments and return values as it does so. So you're not reimplementing all of your C functions; you're just adding some wrappers around the functions that you want to be able to call. Commented Apr 24, 2020 at 13:30
  • Before you dive in to getting it to work on Android, you can already start by interfacing your code with "Desktop Java" by using regular JNI. Commented Apr 24, 2020 at 13:55
  • @Michael So to confirm this new C function i write is not a copy of the original C function it is simply a function that accepts the arguments and calls the original C function thats all.so i end up with original Java class with function that passes the data to my new C function that simply accepts the data and feeds it into the original C function! I assume in the new C function is where the use of JNi with JLong etc is implemented?Still need to find a way of building the original C library to make it work in Android i presume which is also confusing! Commented Apr 24, 2020 at 14:37

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

8 Comments

Thank you for this stepped explanation i will be having a go at it today. Just a quick query, I have no real knowledge of the MatLab code it is a third party company that have provided it. Will i have any chance of writing an Android.mk file for this without knowing how this builds? Just thought i would ask before i start a fight i can't win! Thanks again for your help.
Yeah, it's not so scary, as a first step just try to put all *.c files into LOCAL_SRC_FILES and try to build. Of course something will go wrong. Anyways read this developer.android.com/ndk/guides/android_mk and this stackoverflow.com/questions/34372092/…
Either way even if it's not your code, try to identify those functions which you are going to call in fact. Just narrow down the scope. Think about a JNI, how it will look like. You can just put Android.mk into folder with sources and define a static library module inside, then build with ndk-build, so you will see any problems. I can't predict all problems, but just solve them step by step
Thanks there are only 10 functions i need to pass data to and only one that returns one response object. So i am hoping i will make progress today. You lost me with the static library module, this is really outside my comfort zone! but i will see how far i get today. Really appreciate your help. Thanks.
I will put example Android.mk into my answer
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.