7

postgresql の dart でネイティブ拡張機能を構築しようとしています。CCファイルを.oでコンパイルし、次に.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
4

1 に答える 1

3

コードをいじって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ビルドスクリプトのおかげで、必要なリンクをつなぎ合わせることができました)

于 2012-10-02T19:28:43.243 に答える