原生扩展镖



我正在尝试在dart中为postgresql构建一个本机扩展。我已经在 .o 中编译了 CC 文件,然后在 .so(我猜是共享对象)中编译了 CC 文件。它现在被命名为 libpsql.so 我把它放在与我的 .dart 文件相同的目录中。dart 文件的第一行是 #import(dart-ext:libpsql);但它一直告诉我资源不可用。

我的飞镖代码

#library("psql");
#import("dart-ext:libpsql_dart");
class Database {
  var mDb;
  var mUser;
  var mDbname;
  var mPasswd;
  var mHost;
  var mPort;
  var mTable;
  //String toString() => "<PostgreSQL: $user@$_host:$_port/$_table>";
  Database(host,user,passwd,dbname) : this.mUser = user, this.mHost = host, this.mPasswd = passwd, this.mDbname = dbname  {
    mDb = _connect(host,user,passwd,dbname);
  }
}
_connect(host,user,passwd,dbname) native 'Connect';

这是我C++代码。

#include <string.h>
#include <stdio.h>
#include <libpq-fe.h>
#include "dart_api.h"
Dart_NativeFunction ResolveName(Dart_Handle name, int argc);
DART_EXPORT Dart_Handle psql_dart_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;
}
void Connect(Dart_NativeArguments args) {
    Dart_EnterScope();
    PGconn *conn;
    const char *conninfo = "user=postgres;password=postgres;host=localhost;port=5432;dbname=reviewdb";
    conn = PQconnectdb(conninfo);
    /* Check to see that the backend connection was successfully made */
    if (PQstatus(conn) != CONNECTION_OK)
    {
        fprintf(stderr, "Connection to database failed: %s",
                PQerrorMessage(conn));
        PQfinish(conn);
    }
  Dart_Handle result = HandleError(Dart_NewInteger((int64_t) conn));
  Dart_SetReturnValue(args, result);
  Dart_ExitScope();
}
Dart_NativeFunction ResolveName(Dart_Handle name, int argc) {
  assert(Dart_IsString8(name));
  const char* cname;
  Dart_Handle check_error = Dart_StringToCString(name, &cname);
  if (Dart_IsError(check_error)) Dart_PropagateError(check_error);
  Dart_NativeFunction result = NULL;
  if (strcmp("Connect", cname) == 0) result = Connect;
  Dart_ExitScope();
  return result;
}

网页脚本包括

<script type="application/dart" src="web/lib/psql.dart"></script> 
    <script type="application/dart" src="web/test_dart.dart"></script>

最后,我的编译命令行:

g++ -fPIC --verbose -I/home/{linux user}/Documents/dart/dart-sdk/include/ -lpq -I/usr/include/postgresql -c psql_dart.cc
gcc -shared -Wl,-soname,libpsql.so -o libpsql.so psql_dart.o

测试新代码后,我评论了我的函数 连接如下:

void Connect(Dart_NativeArguments args) {
    Dart_EnterScope();
//    PGconn *conn;
//    const char *conninfo = "user=postgres password=postgres host=localhost port=5432";
//    conn = PQconnectdb(conninfo);
//
//    /* Check to see that the backend connection was successfully made */
//    if (PQstatus(conn) != CONNECTION_OK)
//    {
//        fprintf(stderr, "Connection to database failed: %s",
//                PQerrorMessage(conn));
//        PQfinish(conn);
//        exit(1);
//    }
//  PQfinish(conn);
  Dart_Handle result = HandleError(Dart_NewInteger( 0));
  Dart_SetReturnValue(args, result);
  Dart_ExitScope();
}

输出 :

worked?
Segmentation fault (core dumped)

我仍然知道SegFault吗?

我的 gdb 堆栈跟踪:

Starting program: /home/<user>/Documents/dart/dart-sdk/bin/dart test_dart.dart
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
worked?
Program received signal SIGSEGV, Segmentation fault.
dart::Api::NewHandle (isolate=0x948a40, raw=0x7ffff7f80021) at runtime/vm/dart_api_impl.cc:114
114 runtime/vm/dart_api_impl.cc: No such file or directory.
(gdb) bt
#0  dart::Api::NewHandle (isolate=0x948a40, raw=0x7ffff7f80021) at runtime/vm/dart_api_impl.cc:114
#1  0x000000000042e121 in dart::Dart_Invoke (target=<optimized out>, name=0x959b90, number_of_arguments=<optimized out>, arguments=<optimized out>) at runtime/vm/dart_api_impl.cc:3543
#2  0x00000000004097ee in main (argc=<optimized out>, argv=<optimized out>) at runtime/bin/main.cc:724

在尝试了一些代码并安装了 postgresql-dev-9.1 包之后,这就是我所在的地方。目前它仍然没有运行,但是这是由于链接错误而不是由于导入本身。

请注意对C++文件的更改:我将初始化函数从:psql_dart_Init重命名为仅psql_Init

// libpsql.cc
#include <string.h>
#include <stdio.h>
#include <libpq-fe.h>
#include "dart_api.h"
Dart_NativeFunction ResolveName(Dart_Handle name, int argc);
DART_EXPORT Dart_Handle psql_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;
}
void Connect(Dart_NativeArguments args) {
    Dart_EnterScope();
    PGconn *conn;
    const char *conninfo = "user=postgres;password=postgres;host=localhost;port=5432;dbname=reviewdb";
    conn = PQconnectdb(conninfo);
    /* Check to see that the backend connection was successfully made */
    if (PQstatus(conn) != CONNECTION_OK)
    {
        fprintf(stderr, "Connection to database failed: %s",
                PQerrorMessage(conn));
        PQfinish(conn);
    }
  Dart_Handle result = HandleError(Dart_NewInteger((int64_t) conn));
  Dart_SetReturnValue(args, result);
  Dart_ExitScope();
}
Dart_NativeFunction ResolveName(Dart_Handle name, int argc) {
  assert(Dart_IsString8(name));
  const char* cname;
  Dart_Handle check_error = Dart_StringToCString(name, &cname);
  if (Dart_IsError(check_error)) Dart_PropagateError(check_error);
  Dart_NativeFunction result = NULL;
  if (strcmp("Connect", cname) == 0) result = Connect;
  Dart_ExitScope();
  return result;
}

以下是我的第一个飞镖文件:

// psql.dart
#library("psql");
#import("dart-ext:psql");
class Database {
  var mDb;
  var mUser;
  var mDbname;
  var mPasswd;
  var mHost;
  var mPort;
  var mTable;
  //String toString() => "<PostgreSQL: $user@$_host:$_port/$_table>";
  Database(host,user,passwd,dbname) : this.mUser = user, this.mHost = host, this.mPasswd = passwd, this.mDbname = dbname  {
    mDb = _connect(host,user,passwd,dbname);
  }
}
_connect(host,user,passwd,dbname) native 'Connect';

然后实际的非常小的应用程序(命令行而不是基于dartium的应用程序)来测试它。

// test.dart
#import('psql.dart');
main() {
  var database = new Database('localhost', 'mbutler', 'test', 'test');
  if(database != null) {
    print('worked?');
  }
}

我使用以下命令一次性编译和链接,它确实可以正常工作。我段错误,因为我没有要连接的有效数据库,但以下内容确实正确加载了本机库:

g++ -O2 -DDART_SHARED_LIB -I/home/<user>/dart/dart-sdk/include -rdynamic -fPIC -shared libpsql.cc -lpq -I/usr/include/postgresql -o libpsql.so

(感谢dart-sqlite构建脚本能够拼凑出我需要的链接)

最新更新