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

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

I want to receive data from level C on the client, since the server is written in C ++ (with built-in read / write), and writes the situation with the data into an array variable and wants to define this variable in Java and do what`s matched, I wonder if this is possible?

I thought about writing a file about the current situation on the SD card, however, what is the last thing I want to do, any tips?

+4
source share
2 answers

I recently ran into this problem and was able to solve it. I have an Android C ++ Qt project that needs to execute some Java code (for materials available only from the Android SDK). To achieve this, I had to share some constants between my Java code and C ++ (so that they talk to each other and understand each other).

Here are some possible solutions for this:

  • Let C ++ pass constant values ​​to the Java object upon creation (or vice versa if Java calls C ++). But this is if you have many variables.
  • Have a configuration file that is parsed dynamically with both C ++ and the Java module. Should work, but have not tried.
  • Declaring variables in both places .... a bad idea and hard to maintain
  • Use the declaration file directly ("included") in both C ++ and Java

I finally did the last work on the solution. The idea is to use a java file for both C ++ and Java (the method can work, but I am more like C ++, so it became easier for me). And we use a preprocessor to make this Java file valid for including C ++ as a header file!

Here is an example 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 without problems from any Java code to access variables. Now, 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 

The preprocessor then modifies the .java constants file into this valid C ++ header file (it was mostly difficult to get through the package and import lines because you cannot use dots in macro names .... it should have been 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; } 
+1
source

I did not make any androids - so take this with salt, but you can probably use a buffer with a direct byte. The problem is to know that something has happened. You can simply poll the buffer, but it will not be much better than just using JNI to poll the value.

In regular java, people can use the sun.misc.Unsafe class to do this if they are willing to take the risk. I'm not sure if this class exists in android, but maybe this will help insecure class in Android? .

0
source

Source: https://habr.com/ru/post/1385330/


All Articles