user992537
user992537

Reputation: 73

How to share a variable between Java and C in android JNI?

Is there a way to share a native C variable instantly with Java in android JNI?

I wanna receive data from C layer in client since the server is written in C++(with struct read/write involved),and record the data-coming situation in an array variable,and wanna detect that variable in Java and do what`s correspond, wondering if that is possible?

I considered writing a file about the data-coming situation into sdcard,however that the last thing I wanna do,any tips?

Upvotes: 4

Views: 2402

Answers (2)

jpo38
jpo38

Reputation: 21514

I recently had this problem and could solve it. I have a C++ Qt Android project that needs to execute some java code (for stuff only accessible from Android SDK). To achieve this, I had to share some constants between my java and C++ code (to have them talk together and understand each other).

Here are possible solutions to achieve this:

  • Have C++ pass constants values to Java object upon creation (or the way around if Java invokes C++). But it's apain if you have many variables.
  • Have a config file parsed dynamically by both C++ and Java module. Should work, but did not try it.
  • Declare variables in both places....bad idea and hard to maintain
  • Have a declaration file directly used ('included') by both C++ and Java

I finally made last solution work. The idea is to have a java file being used by both C++ and Java (the way around may work, but I'm more a C++ guy, so this way looked easier to me). And we use pre-processor to make this java file valid to be included by C++ as a header file!

Here is an example of Java file (constants.java) declaring constants (integers and strings):

package name1.name2.name3;
import java.lang.String;

class MyConstants
{
    public static String  THE_NAME() { return "Name"; }
    public static Integer THE_VALUE() { return 12; }
};

This can be used with no problem from any Java code to access variables. Now, here's how to include it from a C++ file:

#include <string>
using namespace std;
#define public public:
#define package struct mockup1 { int name3; };struct mockup2 { mockup1 name2; };int i1 =
#define name1 mockup2()
#define import struct mockup3 { int String; };struct mockup4 { mockup3 lang; };int i2 =
#define java mockup4()
#define String string
#define Integer int

#include "constants.java"

#undef public
#undef String
#undef package
#undef import
#undef java
#undef name3

Pre-processor then changes constants.java file into this valid C++ header file (the main difficuly was to get ride of package and import lines because you cannot use dots in macro names....had to be malicious):

struct mockup1 { int name3; };struct mockup2 { mockup1 name2; };int i1 = mockup2().name2.name3;
struct mockup3 { int String; };struct mockup4 { mockup3 lang; };int i2 = mockup4().lang.String;

class MyConstants
{
    public: static string THE_NAME() { return "Name"; }
    public: static int THE_VALUE() { return 12; }
};

Here you go with your constants in C++!

int main()
{
   cout << MyConstants::THE_NAME() << MyConstants::THE_VALUE() << endl; 

   return 0;
}

Upvotes: 1

sasbury
sasbury

Reputation: 301

I haven't done any android - so take this with a grain of salt - but you could probably use a direct byte buffer. The problem is going to be knowing that something happened. You could simply poll the buffer, but that wouldn't be much better than just using JNI to poll the value.

In regular java, people might take advantage of the sun.misc.Unsafe class for this, if they were willing to take the risk. I am not sure if that class exists in android, but perhaps this will help Unsafe class in Android?.

Upvotes: 0

Related Questions