0

I am in the process of migrating from Android/JNI to Flutter/Dart/FFI to build native apps. Currently in Android I have a Java class (ScanningHelper.java) which is modified during the program lifecycle. During native initialization, I send a jobject type using which in my C/C++ code, I am able to call different member functions or even access variables directly (depending on access).

Is something similar possible with Dart FFI? The closest I have come to is possibly creating a struct in native and then using multiple functions to set/get data from native. I though have a feeling that the amount of code to be written will be high including memory clean up on Dart every time a string/const char* is returned.

Appreciate any direction to accomplish something like below without needing to duplicate implementation across both languages.

// ScanningHelper.java
public class ScanningHelper {

   private String _mediaStorageDirectory;

   public void setMediaStorageDirectory(String path) { _mediaStorageDirectory = path; }
   public String getAppMediaStorageDirectory() { return _mediaStorageDirectory; }
   public double latitude;
   public double longitude;

   ...
   
   byte[] image1Bytes;

}

I have some standard methods defined like getStringFromObjectMethod which allows reuse across different classes and return types;

// JNIMethods.cpp
std::string mediaDirectory = JNIMethods::getStringFromObjectMethod(jniEnv,_scanningHelper,"getAppMediaStorageDirectory"));
                                               
banerjk
  • 335
  • 2
  • 15
  • 1
    You could create a Dart function (note: must be top level or static) for, say, `getLatitude` which you could then call from C to read the current value whenever you need it. You'd need to pass a reference to that callback function down to C. Your idea of setting the potentially needed C values (i.e. set lat/long) *before* making a native call does seem easier. Equally, you could pass lat and long as parameters to the C method that might use them: `void someCFunctionThatMightNeedLatOrLong(xxx, yyy, lat, long)` – Richard Heap Dec 08 '22 at 17:59
  • Thanks @RichardHeap. Currently I have 2 way calls - some initialization from Java(to C) and then C making calls to Java class which is being updated at random intervals. – banerjk Dec 09 '22 at 03:28
  • I guess the closest I can get to that is where I pass a callback reference to C for every function that I need considering they have different return types? – banerjk Dec 09 '22 at 03:34
  • Note that Dart FFI does *not* allow calls from C to Dart at 'random' intervals. Calls from C to Dart may only happen as a direct result of (and during - i.e. on the same thread) a Dart->C call. – Richard Heap Dec 09 '22 at 15:00
  • Yes, figured that thread is another factor to account for. What would be the closest approach to replicate the behavior below: Main thread has an class (object) that maintains state of the system. The object reference is passed to another thread (processing thread). Main thread writes to the state object while processing thread reads from it. Both read & write are done using locks (semaphore) to maintain integrity. Is there a way to accomplish this in dart/flutter using Isolate? – banerjk Dec 11 '22 at 05:29
  • 1
    While common in other languages, those are foreign concepts in Dart. Each isolate has separate memory and they interact by passing relatively simple messages. It does mean that you don't need to worry about synchronisation as you don't have two threads accessing the same memory. – Richard Heap Dec 11 '22 at 13:11
  • Found so after some research, in fact found a thread (lost the page) where there was a debate on process vs thread and then adding shared memory. My approach now is tending to replicate the calls through Isolate messaging passing. More boilerplate code but so be it. Really appreciate you taking time to respond in the weekend. – banerjk Dec 11 '22 at 15:38

0 Answers0