Native Dart Extension

I am trying to create a native extension in dart for postgresql. I compiled the CC file in .o, then in .so (the generic object I assume). Now it is called libpsql.so, and I put it in the same directory as my .dart file. The first line of the dart file is #import (dart-ext: libpsql); but he continues to tell me that resources are unavailable.

My dart code

#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'; 

And here is my C ++ code.

 #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 includes

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

And last, my compiling command line:

 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 

After testing the new code, I commented on my Connect function as follows:

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

Exit:

 worked? Segmentation fault (core dumped) 

And am I still getting the SegFault idea?

My gdb stacktrace:

 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 
+6
source share
2 answers

After you play around your code and get the postgresql-dev-9.1 package installed, I am here. Currently, it still does not start, however, this is due to a communication error not due to the import itself.

Pay attention to changing your file in C ++: I renamed your initialization function from: psql_dart_Init only 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; } 

And the following file is my first file:

 // 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'; 

And then the real VERY minimal application (command line instead of dartium-based) to test it.

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

I used the following command to compile and link at a time, and I am working correctly. I am segfault because I do not have an available database to connect to, but the following correctly loads my own library:

 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 

(Thanks to dart-sqlite build script was able to put together the required link)

+2
source

If you want to compile small projects in C / C ++.

In particular, the expansion of the native dart. Then you can try this small toolbox. This allows you to organize the following tasks.

  • Organize the project into a single file as a yaml or json file.
  • Organize a project to support a multi-platform building.
  • Create these projects directly from Dart scripts.
  • Eliminates the need to write batch files for different platforms.

You can install these tools as a Dart package through the pub package manager and use it.

In addition, it contains a simple example of creating your own extension and an example of how to quickly create it (execute, link, clean up a project) with a Dart language script.

This toolkit is called ccompile .

You can find this toolkit on github at https://github.com/mezoni/ccompile

I hope it will be useful for you!

+2
source

Source: https://habr.com/ru/post/926755/


All Articles