2012-10-02 23 views
6

Estoy tratando de construir una extensión nativa en dardo para postgresql. He compilado el archivo CC en .o luego en .so (objeto compartido, supongo). Ahora se llama libpsql.so y lo coloqué en el mismo directorio que mi archivo .dart. La primera línea del archivo de dart es #import (dart-ext: libpsql); pero me sigue diciendo que los recursos no están disponibles.extensión nativa Dart

Mi código de dardos

#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: [email protected]$_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'; 

Y aquí es mi código 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; 
} 

secuencias de comandos HTML incluye

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

Y la última, mi compilación de línea de comandos:

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 

Después de probar el nuevo código le comenté mi función conectar de esta manera:

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(); 
} 

La salida :

worked? 
Segmentation fault (core dumped) 

¿Y sigo teniendo el SegFault alguna idea?

Mi StackTrace 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 
+0

Probamos compilar con 'g ++ -O2 -DDART_SHARED_LIB -I/home/plaudet/Documentos/dardos/dardos SDK/include -rdynamic -fPIC -shared dart_psql.cc -I/usr/include/PostgreSQL -L/usr /lib/postgresql/9.1/lib -lpq -o dart_psql' Todavía no funciona –

+0

Probé el código mínimo para la Extensión nativa, recompiled, aún no funciona, necesito ayuda de alguien que fue capaz de compilar y ejecutar cualquier extensión nativa dart. Por favor. –

+0

Qué errores recibe actualmente al intentar ejecutar la aplicación (tenga en cuenta que creo que hay un problema con el editor de dart que no reconoce la sintaxis de importación de dart-ext). Pero cuando tratas de ejecutarlo, ¿qué obtienes? Cuando compilé la copia de su información para obtener un archivo 'libpsql.so', y yo #import ('dart-ext: psql'); ve el recurso pero no puede cargarlo (no puede encontrar la función de inicialización) –

Respuesta

2

Después de jugar un poco con su código y conseguir instalado el paquete postgresql-dev-9.1 es aquí donde estoy. Actualmente todavía no se ejecuta, sin embargo, se debe a un error de enlace no debido a la importación en sí.

nota un cambio en su archivo ++ C: Me cambió el nombre a su función de inicialización de: psql_dart_Init sólo 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; 
} 

Y la siguiente es mi primera archivo de dardos:

// 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: [email protected]$_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'; 

Y entonces el real Aplicación MUY mínima (línea de comando en lugar de basada en Dartium) para probarla.

// test.dart 
#import('psql.dart'); 

main() { 
    var database = new Database('localhost', 'mbutler', 'test', 'test'); 

    if(database != null) { 
    print('worked?'); 
    } 
} 

Utilicé el siguiente comando para compilar y vincular de una vez y funcionó correctamente. Me segfault porque no tengo una base de datos válida para conectarse a, pero el siguiente no cargar la biblioteca nativa correctamente:

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 

(Gracias a dart-sqlite script de construcción fue capaz de reconstruir la vinculación que se requiere)

+0

Buen punto, pero todavía tengo el 'Error al cargar el recurso dart-ext: psql' :-( –

2

Si desea compilar los proyectos pequeños en el lenguaje C/C++.

En particular, extensión de dardo nativo. Luego puede probar este pequeño conjunto de herramientas. Le permite organizar las siguientes tareas.

  1. Organice un proyecto en un único archivo como archivo yaml o json.
  2. Organice un proyecto para el soporte de construcción multiplataforma.
  3. Creando estos proyectos directamente desde scripts de lenguaje Dart.
  4. Elimina la necesidad de escribir archivos por lotes para diferentes plataformas.

Puede instalar estas herramientas como paquete Dart a través del administrador de paquetes pub y usarlo.

Además, contiene un ejemplo simple de creación de una extensión nativa y un ejemplo de cómo compilarla rápidamente (compilar, vincular y limpiar proyecto) desde el script del lenguaje Dart.

Este conjunto de herramientas se llama ccompile.

Puede encontrar este conjunto de herramientas en GitHub en https://github.com/mezoni/ccompile

espero que esto sea útil para usted!

+0

Ya eché un vistazo a ese proyecto, comencé con este proyecto. Para las herramientas de ccompilación lo estoy viendo con mi jefe. Gracias. –