Tutorial: Use C code in your Reactive Block application with JNA

Summary

These tutorials explains how to use foreign (as in non-Java) code in your Reactive Block application. Another term for foreign is native, because embedding non-Java code usually introduces platform and portability issues.

Make sure you have read the intro foreign-code-intro to prepare what you need for this tutorial.

Doing the tutorial

Alt text

Download the tutorial named “(Level 3) Foreign code v3: JNA”

Part 1 - Build shared library on Raspberry-Pi

  • Look at the project in the Package Explorer view. You will see the c-code directory. Inside there you will find four files, one script, one header file and two cpp files.

Alt text

  • Transfer the files to your Raspberry-Pi. You may need to set the execute bit on the script.
  • Compile shared library with command: buildall.sh
  • The shared library is called libwd-jna.so
  • Test the shared library with separate test program test-wd-jna. Note that you may need to set LD_LIBRARY_PATH

Alt text

Part 2 - Understand functions of shared library

Alt text

The functions we are going to make available from Java are:

  • void setWdDeviceName(const char *deviceName);: Set filename of watchdog device.
  • const char *getWdErrorMessage();: Gets most recent error message. The message is allocated in C heap and a pointer is returned to Java application.
  • void clearWdErrorMessage();: Clear last error message and release memory.
  • int enableWd(int timeout);: Enable watchdog, parameter is timeout value.
  • int getWdRemainingTime();: Returns remaining time until watchdog fires, this is similar to the stupid countdown timer on all atomic bombs in old James Bond movies.
  • int getWdTimeout();: Return current timeout value.
  • int disableWd();: Disable watchdog
  • int heartbeatWd();: Send heartbeat to reset watchdog counter.
  • void closeWd();: Close files and release memory.

All int return values < 0 indicates error.

Note that even if this is compiled as a C-program, you can use C++ from the different methods as long as you dont expose that in the header files.

Part 3 - Generate Java class for shared library

Download and launch JNAeratorStudio from this page and launch it. It is (still) written in Java and some browsers (eg. Chrome) may refuse to download it.

Alt text

Generate Java class to interface shared library like this:

  • Paste the code from wd-jna.h into work window
  • Set Target Runtime to Jna
  • Set Output Mode to Jar
  • Set Library name to wd-jna
  • Press JNAerate!

The generated file will appear to the right. You can also do this process manually, but using this tool gives you a good starting point.

In the project you downloaded earlier you will see the generated file (src/com/bitreactive/tutorial/foreigncode/jna/wdjna/WatchdogInterface.java) is already in place. You can replace it with the one that is generated now. You will need to change package name and classname, but other than that no changes needs to be done.

In addition you must add jna.jar library to the project. (This has also already been done).

Now you are ready to use the C library from your Reactive Blocks application.

You can also read more about more complex datatypes than const char * here. It is relatively straight forward.

Part 4 - Understand reactive block and functions

Alt text

The block is shown in the image above and with exception of the init and stop pin, all functions are the same as in the C library. In addition we have added a state check to query if watchdog is enabled.

We will take a closer look at some functions:

init and stop functions:

Alt text

  • The C interface is automatically loaded on application start.
  • Java String are automatically converted to C const char * when used as parameter
  • When C const char * is returned, there are functions available to easy convert that to Java String.

Alt text

enable functions does take one parameter, the watchdog time which is transferred to C library.

Part 5 - Build application and execute on Raspberry-Pi

  • Select Test WD JNA application, press Build from rightclick menu and build Java project. Select Java SE as project type.

  • Export the generated project (located in com.bitreactive.tutorial.foreigncode.jna.testwdjna_exe) as Runnable JAR and transfer to your Raspberry-Pi to the same directory as the shared library you generated in part 3.

Alt text

  • Try it (Hint: Note you have to use sudo because of file rights)

Alt text