Native extensions - C++ native libraries Native extensions - C++ native libraries dart dart

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.