Chapter 9. Writing Native Extensions for the Standalone Dart VM

This is the last chapter. We'll look at a slightly more advanced topic, which is writing native extensions in C/C++ for the standalone Dart VM. Don't worry if you've never seen C or C++; we'll use a very intuitive approach while trying to stay practical. In this chapter, we'll work on two examples:

  • Writing a fuzzy search algorithm as a C++ class and comparing its performance with the implementation shown in Chapter 2, Practical Dart
  • Writing bindings for the exiv2 library to read EXIF image metadata

The main purpose of this chapter is to give you the whole picture of Dart as a language. Most of the time, you probably won't write native extensions even when using Dart as a server-side language. In this chapter, we want to show you the enormous and nearly unlimited potential of Dart.

The structure of native extensions

All native extensions in Dart are compiled as shared (also called dynamic) libraries and have to implement two main functions:

  • The <extension_name>_Init() function that is called by the Dart VM when the extension is loaded. Most importantly, it registers a handler that returns references to the extension's functions (typically called ResolveName()). We can use it to initialize some local variables, but most of the time, you'll use the default function from the example given by the Dart team. We'll use the default one here as well.
  • The ResolveName() function is called when we use the native keyword in Dart and is used to map functions from native extensions to Dart functions.

Typically, there's also a Dart class that wraps all calls to the native extension.

It's worth noting that there are conventions and caveats we have to follow. Otherwise, Dart won't be able to load our extension with quite an ambiguous error message: library handler failed. The premises are as follows:

  • The filename must be prefixed with lib. For example, when importing a native extension called hello_extension, Dart is looking for a libhello_extension.dll file (.so for Unix-based systems or .dylib for OS X).
  • Mind your Dart VM's build architecture. Even on 64-bit systems, it's very likely that you're running a 32-bit Dart VM that requires all native extensions to be built as 32-bit binaries. This implies that all libraries linked by your extension have to be compiled as 32-bit libraries. Of course, we can use universal libraries that contain both 32-bit and 64-bit builds.
  • The <extension_name>_Init() function has to be defined even if you're not using it. For example, for the hello_extension extension, it has to be called hello_extension_Init(). Mind the capital "I".

For a more in-depth description about the compilation process and how to set up IDEs for various systems, refer to the official guide at https://www.dartlang.org/articles/native-extensions-for-standalone-dart-vm.

There are two types of extensions: synchronous, which run on Dart's main thread, and asynchronous, which don't block the main thread and communicate with Dart via ports. In this chapter, we'll use only synchronous extensions because they use a more intuitive approach and basically don't require any Dart code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.45.80