How do I Print to Console using dart:ffi in Flutter?
Asked Answered
W

1

9

Trying to print to console when running my Flutter app (on Android) from the following C++ code I am running through dart:ffi:

#include <iostream>

std::cout << "Hello, World!";

Does not give me any output in the terminal. How would I print to the Flutter terminal from C++?


I know my functions otherwise work correctly because I am getting correct actions on pointers / return values.

Wallford answered 7/3, 2020 at 12:59 Comment(2)
Are you able to use __android_log_print(ANDROID_LOG_VERBOSE,...? Would need a conditional include as obviously Android only.Barghest
@RichardHeap Thank you for pointing it out. I tried #ifdef __ANDROID_API__ #include <android/log.h> #endif and used it according to https://mcmap.net/q/691241/-android-ndk-__android_log_print-function-and-logcat. It seems I would need to include it as https://mcmap.net/q/203428/-undefined-reference-to-__android_log_print-39 says. However, that would only show up in Logcat and I want to read the output in the Flutter console.Wallford
E
11

Edit: When only running on android, there is a simpler way. I have updated the answer below.

You'll have to pass a wrapper to the print function into the native code

void wrappedPrint(Pointer<Utf8> arg){
  print(Utf8.fromUtf8(arg));
}

typedef _wrappedPrint_C = Void Function(Pointer<Utf8> a);
final wrappedPrintPointer = Pointer.fromFunction<_wrappedPrint_C>(_wrappedPrint_C);

final void Function(Pointer) initialize =
  _nativeLibrary
    .lookup<NativeFunction<Void Function(Pointer)>>("initialize")
    .asFunction<void Function(Pointer)>();

initialize(wrappedPrintPointer);

and then use that in your C library:

void (*print)(char *);

void initialize(void (*printCallback)(char *)) {
    print = printCallback;
    print("C library initialized");
}

void someOtherFunction() {
    print("Hello World");
}

When only running on android, things get simpler. Instead of all of the above, do:

Simply use the android logging mechanism, it will show up on the console, at least when using flutter run. I'm assuming flutter attaches to logcat using the app's PID.

To do so, update the CMakeLists.txt with:

find_library( # Defines the name of the path variable that stores the
              # location of the NDK library.
              log-lib

              # Specifies the name of the NDK library that
              # CMake needs to locate.
              log )

# Links your native library against one or more other native libraries.
target_link_libraries( # Specifies the target library.
                       <your-libs-name-here>

                       # Links the log library to the target library.
                       ${log-lib} )

and in your c lib do:

#include <android/log.h>

void someOtherFunction() {
      __android_log_print(ANDROID_LOG_DEBUG, "flutter", "Hello world! You can use %s", "formatting");
}
Extremely answered 15/5, 2020 at 15:53 Comment(2)
Very helpful! Thank you.Sclerotic
It seems that as of May 2021 (ffi v 1.0.0) the first solution doesn't seem to work, I get the error dart:ffi only supports calling static Dart functions from native code.Comras

© 2022 - 2024 — McMap. All rights reserved.