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:
exiv2
library to read EXIF image metadataThe 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.
All native extensions in Dart are compiled as shared (also called dynamic) libraries and have to implement two main functions:
<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.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:
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).<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.
18.218.45.80