سؤال

أحاول إنشاء امتداد أصلي في Dart لـ postgresql.لقد قمت بتجميع ملف CC في .o ثم في .so (كائن مشترك على ما أعتقد).أصبح اسمه الآن libpsql.so وقد قمت بوضعه في نفس الدليل مثل ملف .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
هل كانت مفيدة؟

المحلول

بعد تجربة بعض التعليمات البرمجية الخاصة بك وتثبيت حزمة 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';

ثم التطبيق الفعلي البسيط جدًا (سطر الأوامر بدلاً من المستند إلى الدارتيوم) لاختباره.

// 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 كان إنشاء البرنامج النصي قادرًا على تجميع الارتباط الذي طلبته)

نصائح أخرى

إذا كنت ترغب في ترجمة المشروعات الصغيرة في اللغة C / C ++.

على وجه الخصوص ملحق DART الأصلي. ثم يمكنك تجربة هذه المجموعة الصغيرة واحدة من الأدوات. يسمح لك بتنظيم المهام التالية.

  1. قم بتنظيم مشروع في ملف واحد كملف Yaml أو JSON.
  2. تنظيم مشروع لدعم مبنى متعدد المنصات.
  3. بناء هذه المشاريع مباشرة من البرامج النصية لغوية DART.
  4. يلغي الحاجة إلى كتابة ملفات الدفعات لمنصات مختلفة.
  5. يمكنك تثبيت هذه الأدوات كحزمة DART من خلال إدارة حزمة Pub واستخدامها.

    أيضا، يحتوي على مثال بسيط لإنشاء امتداد أصلية ومثال على كيفية إنشاءه بسرعة (يشكك، وصلة ومشروع نظيف) من برنامج نصي لغة DART.

    مجموعة الأدوات هذه تسمى cCompile .

    يمكنك العثور على هذه المجموعة من الأدوات على Github في https://github.com/mezoni/ccompile هذا >

    آمل أن يكون هذا مفيدا لك!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top