2014-01-16 32 views
4

對於C庫鏈接,samples_extension工作正常,但C++庫如何?本機擴展 - C++本機庫

我有++庫我想作爲一個原生擴展使用基於類的C,所以我們有,例如: -

class Connect { 
     open(...); 
    .... 
} 

在C++中,我想在DART相似的類。

看着dart_api.h和dart_native_api.h,我不清楚我是如何將類指針從C++傳遞到Dart的,以及如何在它們上調用方法並將其綁定到Dart類實例。 ResolveName如何與connection-> open()類型的調用一起工作,或者我們完全不同的做法。

回答

2

OK,挖掘一下的,我現在已經sussed這一點,我這樣做是在飛鏢: -

bool open() native 'Connection::open'; 

,在我的解析器尋找字符串「連接::開」然後調用本地功能。 所以,這意味着我的本地函數被命名爲'connectionOpen'和'messageOpen'等,所以我可以解決這些問題。

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

其他在這個包所需的文件。

運行:

  • 斌/ build_cpp_extension.dart
  • 斌/ use_cpp_extension.dart

附:

我不是C++程序員。

請原諒我對這種語言的任何錯誤。

+0

是的,我知道這一點,我想這樣做的擴展庫「myclass-> getVersionString()」不getVersionString()一個靜態調用,因此我需要輸入飛鏢扎對象對我實例化的類在本機側。我想我需要使用weakpersistenthandles和Dart_Invoke API調用,有什麼我不能確定的是如何在DART解決這個「布爾開放(字符串URL)原生‘連接::開放’;」到使用ResolveName的命名函數。 – user2685314