FFI means foreign function interface, which is a mechanism by which a program written in one programming language can call routines or make use of services written in another programming language.Dart:ffi it's the implementation of a foreign function interface, which allows a program is written in dart to call routines or make use of services written in C (or C++ if and only it exposes a C compatible interface).
1.Create a plugin
To create a plugin called “native_add”, do the following:
To use the same C code in ios and android, you need to write the source code in the ios folder.The reason is that in the case of ios, the source file located higher than the podsepc file cannot be included, and in Android, it can be used only by specifying the location.Then, let's create the native_add.cpp file in the ios/Classes folder location as shown below.After creating the file, add the code as below.
# include <stdint.h> extern "C" __attribute__ ( ( visibility ( "default" ) ) ) __attribute__ ( ( used ) ) int32_t native_add ( int32_t x , int32_t y ) { return x + y ; }
The source content is very simple. It is a function that takes two integers (x, y), adds them, and returns them.
3. C code build settings
The build settings must be done for ios and android respectively, but ios has not been tested.
3-1. ios setup-test X
For ios, you need to tell XCode to link the code statically. -I'll deal with it later if I have a chance.-Open Runner.wxworkspace file in Xcode and add the source file to Xcode project
3-2. Android settings
Create CMakeLists.txt file under android folder.
If you have created the CMakeLists.txt file, add the contents as follows.
cmake_minimum_required ( VERSION 3.4 .1 ) # for Example add_library ( native_add # Sets, , Is the AS Ares Is the Library Is the Shared Library . SHARED # Ares for Provides for Your Relative Is the path to the Source File (S). . . / iOS / Is the Classes / native_add . cpp )
CMakeLists.txt Description
4.Library name native_add
Make it in the form of a dynamic library
CMake requires at least 3.4.1
Build the ../ios/Classes/native_add.cpp file
If you build with the above configuration, the libnative_add.so file is created.For reference, CMake is known to be installed by default in Android SDK Manager (SDK Tools).
If you have added the contents of CMakeLists.txt, open the android/build.gradle file and add CMakeLists.txt to be referenced as shown below.
android { // ... externalNativeBuild { // Encapsulates your CMake build configurations. cmake { // Provides a relative path to your CMake build script. path "CMakeLists.txt" } } // ...
}
Calling C code functions using the FFI library
import 'DART: FFI' ; : import 'DART: io' ; final DynamicLibrary nativeAddLib = Platform . isAndroid ? DynamicLibrary . open ( "libnative_add.so" ) : DynamicLibrary . process ( ) ;
The above code is to create a handler that can be controlled by loading the native code library, but there is also a difference between ios and Android, so you need to compare and separate the platforms.Android dynamically loads the distributed file (libnative_add.so) with the library name specified in CMakeLists.txt, and in the case of ios, because it is a static library type, it loads it with the process function.
4-2. C code and flutter function mapping
Now let's use this handler to access a C code function (symbol in the library).Add the following content just below the handler creation (nativeAddLib) code.
1 2 3 4 final int Function ( int x , int y ) nativeAdd = nativeAddLib . lookup < NativeFunction < Int32 Function ( Int32 , Int32 ) >> ( "native_add" ) . asFunction ( ) ;
It feels similar to Android NDK (JNI).I think you can just cook and use this form as it is.Ready to use native_add function suitable for C code in flutter (dart).Let's check if there are any problems while using it in an actual example project.
Test C code function calls in the Example project
Open example/lib/main.dart and change the body part of the build function as shown below.
body : Center ( child : Text ( 'Running on: $_platformVersion\n' ) , ) , change as follows body : Center ( child : Text ( '1 + 2 == $(nativeAdd(1, 2)}' ) , )
How to debug
Android Studio (or VS Code) doesn't support native (C/C++) code debugging while in Flutter mode (yet). However, there is a workaround! In the project tree, right-click the android' folder and select Flutter -> Open Android module in Android Studio. The project will switch to Android development mode where c/c++ debugging is fully supported. Now just search for the'cpp' folder, set breakpoints in any of the files there, and run the app (while still in the Android development mode of course)!