samples_extension与C库链接正常,但C ++库呢?
我有一个基于类的C ++库我想用作本机扩展,所以我们有例如: -
class Connect {
open(...);
....
}
在C ++中,我想在Dart中使用类似的类。
看看dart_api.h和dart_native_api.h,我不清楚如何从C ++到Dart来回传递类指针,以及如何调用它们上的方法并将其绑定回Dart类实例。 ResolveName如何使用connection-> open()类型调用,或者我们是否完全采用不同的方式。
答案 0 :(得分:5)
可以获得问题答案的基本项目:
<强> 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");
}
这是github上的基本(可立即使用)包:https://github.com/mezoni/dart_and_cpp_classes
此软件包中的其他必需文件。
执行命令
P.S。
我不是C ++程序员。
请原谅我这种语言的任何不准确之处。
答案 1 :(得分:3)
好的,有点挖掘,我现在已经怀疑了,我在Dart做这个: -
bool open() native 'Connection::open';
并在我的解析器中查找字符串'Connection :: open'然后调用本机函数。 所以,这意味着我的原生函数被命名为'connectionOpen'和'messageOpen'等等,所以我可以解决这些问题。