The original address: levelup.gitconnected.com/dart-ffi-an…

Original author: medium.com/aseemwango…

Published: 23 November 2020-5 minutes to read

Dart FFI and CLI applications

How to use THE Dart FFI and create a CLI App? B: well…

The integration of the Flutter resources: flatteredwithflutter.com/dart-ffi-cl…

Meetup Talk:

www.youtube.com/watch?v=xMd…

www.youtube.com/watch?v=jKb…

The Dart FFI and CLI

Began to…

Level. The intermediate

Prerequisites. Install FFI and Args packages

We’ll give you a brief introduction

  1. Use the Dart FFI
  2. Get the user’s login history (macOS)
  3. Create a CLI application

Note: We won’t go into detail about THE Dart FFI because there are good articles about it.

Dart FFI and CLI applications


1. Dart FFI

FFI. (Foreign Function Interface) can be used to call C/C++ based apis.

Dart FFI and CLI applications

The static link library is embedded in the executable image of the application and loaded when the application starts.

You can use DynamicLibrary. The executable or DynamicLibrary. The process load in the static link library symbols.

Dynamically linked libraries are distributed in a separate file or folder within the application and loaded on demand. Dynamic link libraries can be loaded into Dart via DynamicLibrary.open.

How will we get close?

In this article, we will utilize the dynamic systems library.

If you want to create your own dynamic library, read this.


2. Obtain user login history (macOS)

Open the terminal and enter the following command

last login `username`
where username is before @ [username@Macbook-Pro]
Copy the code
  • You should get your login history. Our goal is to invoke this command in Dart.
  • This command is defined in the System dynamics library and exists in macOS.

In macOS, the system inventory is

/usr/lib/libSystem.dylib
Copy the code

To get paths for different operating systems, visit here.

We will load our dynamic library in Dart, in the path specified above.

Dart FFI and CLI applications

  • Import the DART FFI package (which exists within a Flutter) as
import 'dart:ffi' as ffi
Copy the code

There’s a DynamicLibrary class. We call this method to open and load our dynamic library (dylibs.systemdylib).

class Dylibs {
  static const String systemDyLib = '/usr/lib/libSystem.dylib';
  static const String systemSymbolName = 'system';
}
Copy the code

Every dynamic library is made up of symbols. For information on how to find symbols in the library, see here.

Getting the user login history is now a system symbol.

Dart FFI and CLI applications

  • Use lookupFunction to find symbols from the loaded dynamic library.

We specify SystemC and SystemDart functions, basically

// C header typedef:
typedef SystemC = ffi.Void Function(ffi.Pointer<Utf8> command);
// Dart header typedef
typedef SystemDart = void Function(ffi.Pointer<Utf8> command);
Copy the code

This is combined with the lookup function and projected into the Dart function.

  • Next, we convert the command (our last login command) into something that C understands, using
/// Convert a [String] to a Utf8-encoded null-terminated C string.
/// Returns a malloc-allocated pointer to the result.
final cmd = Utf8.toUtf8(command);
Copy the code
  • Run the commands using sysFunc(CMD).
  • Finally, free up memory, since C/C++ has no garbage collection.

3. Create a CLI application program

We will create our own commands, which will have information and descriptions about the CLI application.

Dart FFI and CLI applications

  • Create our command

We CommandRunner and define our command (last_login) and add some description as

In the CLI CommandRunner

  • Add our last login command. To create your own commands, you need to extend the command class.
// THIS ADDS OUR LAST LOGIN COMMAND
runner.addCommand(LastLoginCmd());
Copy the code

Note: LastLoginCmd is our custom class.

We create an abstract base command class and declare methods.

abstract class BaseCLICommand extends Command<dynamic> {
  String loadingMessage;
  void execCommand(String arg);
  @override
  Future<void> run() async {
    if (argResults.arguments.isEmpty) {
      throw Exception('😳😳 Please specify the argument');
    }
    final arg = argResults.arguments.first;
    final loadingMsg = '$loadingMessage $arg';
    stdout.write('$loadingMsg\n'); execCommand(arg); }}Copy the code
  • Argresults.arguments helps us get user input.
  • Stdout. write is used to print to the console.
  • ExecCommand is a function that extends the class definition.

Our LastLoginCmd extends the above classes and implements these methods.

LastLoginCmd

  • After we add the commands above
// THIS ADDS OUR LAST LOGIN COMMAND
runner.addCommand(LastLoginCmd());
Copy the code

Finally, we take

runner.run(args);
Copy the code

Final step (convert to CLI application

We used Dart 2 Native, which compiles the Dart program into its own executable. With Dart 2 Native, you can use Dart to create command-line tools on macOS, Windows, or Linux.

  1. Navigate to the directory that contains your Dart entry point. For example,

My directory is lib/ffi

  1. Run the command
dart2native cmd_line.dart -o login_history
Copy the code

-o or –output= generates output.

This will create our CLI application, named login_history.

The final output

Interesting articles about Flutter are here.

  • Medium.com/codechai/fl…
  • Medium.com/flutter-com…
  • Medium.com/codechai/fl…

Flutter desktop application source.


Translation via www.DeepL.com/Translator (free version)