【问题标题】:native extension Dart原生扩展 Dart
【发布时间】:2012-09-23 07:54:36
【问题描述】:

我正在尝试在 dart 中为 postgresql 构建本机扩展。我已经在 .o 中编译了 CC 文件,然后在 .so 中编译(我猜是共享对象)。它现在命名为 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;
}

Html 脚本包含

<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

在测试新代码后,我这样评论了我的函数 Connect :

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

【问题讨论】:

  • 试过用g++ -O2 -DDART_SHARED_LIB -I/home/plaudet/Documents/dart/dart-sdk/include -rdynamic -fPIC -shared dart_psql.cc -I/usr/include/postgresql -L/usr/lib/postgresql/9.1/lib -lpq -o dart_psql编译还是不行
  • 尝试了本机扩展的最小代码,重新编译,仍然无法工作,需要能够编译和运行任何 dart 本机扩展的人的帮助。请。
  • 在尝试运行应用程序时,您当前收到了哪些错误(请注意,我认为 dart-editor 存在问题,无法识别 dart-ext 导入语法)。但是,当您尝试运行它时,您会得到什么?当我编译复制您的信息以获取“libpsql.so”文件时,我 #import('dart-ext:psql');它确实看到了资源但无法加载它(找不到初始化函数)
  • 啊,我没有收到那个错误,我收到了 Failed to load resource dart-ext:psql 两次
  • 我现在遇到一个错误,它找不到某些符号(似乎是链接问题)。我将使用我目前拥有的所有文件(包括文件名等)在下面编辑我的答案。

标签: postgresql web native dart


【解决方案1】:

在玩弄了一些代码并安装了 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 构建脚本能够拼凑出我需要的链接)

【讨论】:

  • 好点,但我还是得到了Failed to load resource dart-ext:psql :-(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 2021-08-31
  • 2017-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多