Native extensions - C++ native libraries
Basic project that can get answers to your questions:
cpp_extension.cc
#include <string.h>#include <stdlib.h>#include <stdio.h>#ifdef _WIN32#include "windows.h"#else#include <stdbool.h>#include <dlfcn.h>#include <unistd.h>#include <sys/mman.h>#endif#include "dart_api.h"Dart_NativeFunction ResolveName(Dart_Handle name, int argc, bool* auto_setup_scope);DART_EXPORT Dart_Handle cpp_extension_Init(Dart_Handle parent_library) { if (Dart_IsError(parent_library)) { return parent_library; } Dart_Handle result_code = Dart_SetNativeResolver(parent_library, ResolveName); if (Dart_IsError(result_code)) return result_code; return Dart_Null();}Dart_Handle HandleError(Dart_Handle handle) { if (Dart_IsError(handle)) Dart_PropagateError(handle); return handle;}class Connection { int* buffer; bool opened; public: Connection() { opened = false; buffer = new int[1000000]; memset(buffer, 1, 1000000); } void close() { opened = false; } void open(const char* connectionString) { opened = true; } ~Connection() { delete buffer; }};void ConnectionClose(Dart_NativeArguments arguments) { Connection* connection; Dart_Handle dh_handle; Dart_EnterScope(); dh_handle = Dart_GetNativeArgument(arguments, 0); connection = (Connection*)dh_handle; connection->close(); Dart_Handle result = Dart_Null(); Dart_SetReturnValue(arguments, result); Dart_ExitScope();}void ConnectionCreate(Dart_NativeArguments arguments) { Connection* connection; Dart_Handle result; Dart_EnterScope(); connection = new Connection(); result = Dart_NewInteger((int64_t)connection); Dart_SetReturnValue(arguments, result); Dart_ExitScope();}void ConnectionPeerFinalizer(Dart_WeakPersistentHandle handle, void *peer) { delete (Connection*) peer;}void ConnectionPeerRegister(Dart_NativeArguments arguments) { int64_t peer; Dart_Handle dh_object; Dart_Handle dh_peer; Dart_EnterScope(); dh_object = Dart_GetNativeArgument(arguments, 0); dh_peer = Dart_GetNativeArgument(arguments, 1); Dart_IntegerToInt64(dh_peer, &peer); Dart_NewWeakPersistentHandle(dh_object, (void*)peer, ConnectionPeerFinalizer); Dart_SetReturnValue(arguments, Dart_Null()); Dart_ExitScope();}void ConnectionOpen(Dart_NativeArguments arguments) { Connection* connection; const char* connectionString; Dart_Handle dh_connectionString; Dart_Handle dh_handle; Dart_EnterScope(); dh_handle = Dart_GetNativeArgument(arguments, 0); dh_connectionString = Dart_GetNativeArgument(arguments, 1); Dart_StringToCString(dh_connectionString, &connectionString); connection = (Connection*)dh_handle; connection->open(connectionString); Dart_Handle result = Dart_Null(); Dart_SetReturnValue(arguments, result); Dart_ExitScope();}struct FunctionLookup { const char* name; Dart_NativeFunction function;};FunctionLookup function_list[] = { {"ConnectionClose", ConnectionClose}, {"ConnectionCreate", ConnectionCreate}, {"ConnectionOpen", ConnectionOpen}, {"ConnectionPeerRegister", ConnectionPeerRegister}, {NULL, NULL}};Dart_NativeFunction ResolveName(Dart_Handle name, int argc, bool* auto_setup_scope) { if (!Dart_IsString(name)) return NULL; Dart_NativeFunction result = NULL; Dart_EnterScope(); const char* cname; HandleError(Dart_StringToCString(name, &cname)); for (int i=0; function_list[i].name != NULL; ++i) { if (strcmp(function_list[i].name, cname) == 0) { result = function_list[i].function; break; } } Dart_ExitScope(); return result;}
cpp_extension.dart
library dart_and_cpp_classes.ext_cpp_extension;import "dart-ext:cpp_extension";class Connection { final String connectionString; int _handle; bool _opened = false; Connection(this.connectionString) { _handle = _create(); _peerRegister(this, _handle); } bool get opened => _opened; void close() { _close(_handle); _opened = false; } void open() { _open(_handle, connectionString); _opened = true; } int _create() native "ConnectionCreate"; void _close(int handle) native "ConnectionClose"; void _open(int handle, String connectionString) native "ConnectionOpen"; void _peerRegister(Object object, int handle) native "ConnectionPeerRegister";}
use_cpp_extension.dart
import 'package:dart_and_cpp_classes/cpp_extension.dart';void main() { var count = 500; var connections = []; for(var i = 0; i < count; i++) { var connection = new Connection("MYSQL"); connection.open(); connection.close(); connections.add(connection); } connections = null; print("Done");}
Here is basic (ready to use) package on github: https://github.com/mezoni/dart_and_cpp_classes
Other required files in this package.
Run:
- bin/build_cpp_extension.dart
- bin/use_cpp_extension.dart
P.S.
I am not C++ programmer.
Please, forgive me for any inaccuracies in this language.
OK, a bit of digging and I've sussed this now, I'm doing this in Dart :-
bool open() native 'Connection::open';
and in my resolver looking for the string 'Connection::open' then calling a native function.So, this means my native functions are named 'connectionOpen' and 'messageOpen' etc. so I can resolve these.