digitalmars.D.learn - #import mapi.h
- Martin Tschierschke (11/11) Mar 21 2018 Is there an step by step introduction how to convert a C header
- ketmar (6/7) Mar 21 2018 ok, tutorial:
- Timoses (8/12) Mar 21 2018 While googling I found this:
- Martin Tschierschke (7/20) Mar 22 2018 Thank you! I will have a look at both, an Mike Parker is pointing
- Martin Tschierschke (90/91) Mar 22 2018 [...]
- nkm1 (132/143) Mar 21 2018 The easiest thing to do is to write a wrapper in C. The wrapper
- Martin Tschierschke (3/16) Mar 22 2018 Thank you!
- Kagamin (5/7) Mar 22 2018 In short, they should be binary compatible: where is a pointer on
- Paul Backus (5/7) Mar 22 2018 In addition to what others have said, I found the following
- Martin Tschierschke (2/9) Mar 22 2018 Thank you, this one is very good!
- Mike Parker (3/14) Mar 22 2018 If you have Learning D, chapter 9 is all about interface D with C.
- Martin Tschierschke (12/28) Mar 23 2018 I will look at it! I have seen your hint already, you have
Is there an step by step introduction how to convert a C header
of an external lib into the right extern(C){} block?
A blog post or tutorial, or chapter in a D book? (I have those
from Packt Publishing)
(Especially I am trying to get this used with D:
Montetdb C-API
https://www.monetdb.org/Documentation/Manuals/SQLreference/Programming/MAPI
With:
https://github.com/snaga/monetdb/blob/master/clients/mapilib/mapi.h)
The page: https://dlang.org/spec/interfaceToC.html is known, but
not detailed enough for me.
Mar 21 2018
Martin Tschierschke wrote:or tutorialok, tutorial: 1. learn C. 2. learn D. 3. DO IT! ;-)
Mar 21 2018
On Wednesday, 21 March 2018 at 16:22:45 UTC, Martin Tschierschke
wrote:
Is there an step by step introduction how to convert a C header
of an external lib into the right extern(C){} block?
A blog post or tutorial, or chapter in a D book? (I have those
from Packt Publishing)
While googling I found this:
https://dlang.org/blog/2017/12/05/interfacing-d-with-c-getting-started/
Haven't read it yet, but might give you some more insight.
For automatic conversion I stumbled across Dstep which I so far
like a lot:
https://github.com/jacob-carlborg/dstep
Mar 21 2018
On Wednesday, 21 March 2018 at 17:12:07 UTC, Timoses wrote:On Wednesday, 21 March 2018 at 16:22:45 UTC, Martin Tschierschke wrote:Thank you! I will have a look at both, an Mike Parker is pointing to his book, too, so now together with the post from "nkm1" I should be able to make it! ketmar, I learned C but the counter of years from that time was stored in a nibble and so I got an overflow...error :-)Is there an step by step introduction how to convert a C header of an external lib into the right extern(C){} block? A blog post or tutorial, or chapter in a D book? (I have those from Packt Publishing)While googling I found this: https://dlang.org/blog/2017/12/05/interfacing-d-with-c-getting-started/ Haven't read it yet, but might give you some more insight. For automatic conversion I stumbled across Dstep which I so far like a lot: https://github.com/jacob-carlborg/dstep
Mar 22 2018
On Thursday, 22 March 2018 at 12:53:23 UTC, Martin Tschierschke wrote:On Wednesday, 21 March 2018 at 17:12:07 UTC, Timoses wrote:[...] I got it, my first mini test with C bindings! Important missing at first: (stderr) import core.stdc.stdio : stderr, FILE; and use of toStringz inside: mapi_query(dbh, toStringz(q) ) After installing monetdb and starting the server with: https://www.monetdb.org/Documentation/UserGuide/Tutorial My minimal version of the example compiled with dmd app.d -I /usr/local/lib/libmapi.so (My dub.json is still incomplete so the linking failed.) Here is the code: (only the minimum of mapi.h is icluded!) ``` std.stdio; import std.string; /* interfacing winth monetdb #include mapi.h */ /* minimum to run code of example at: https://www.monetdb.org/Documentation/Manuals/SQLreference/Programming/MAPI */ import core.stdc.stdio : stderr,FILE; import core.stdc.stdlib; struct MapiStruct; alias Mapi = MapiStruct*; struct MapiStatement; alias MapiHdl = MapiStatement*; enum MOK = 0 ; alias MapiMsg = int; extern(System){ Mapi mapi_connect(const char* host, int port, const char* username, const char* password, const char* lang, const char* dbname); MapiHdl mapi_query(Mapi mid, const char *cmd); int mapi_fetch_row(MapiHdl hdl); char *mapi_fetch_field(MapiHdl hdl, int fnr); MapiMsg mapi_error(Mapi mid); MapiMsg mapi_explain(Mapi mid, FILE* fd); MapiMsg mapi_destroy(Mapi mid); MapiMsg mapi_close_handle(MapiHdl hdl); MapiMsg mapi_explain_result(MapiHdl hdl, FILE* fd); MapiMsg mapi_next_result(MapiHdl hdl); MapiMsg mapi_explain_query(MapiHdl hdl, FILE* fd); char *mapi_result_error(MapiHdl hdl); } void die(Mapi dbh, MapiHdl hdl) { if (hdl != null) { mapi_explain_query(hdl, stderr); do { if (mapi_result_error(hdl) != null) mapi_explain_result(hdl, stderr); } while (mapi_next_result(hdl) == 1); mapi_close_handle(hdl); mapi_destroy(dbh); } else if (dbh != null) { mapi_explain(dbh, stderr); mapi_destroy(dbh); } else { fprintf(stderr, "command failed\n"); } exit(-1); } MapiHdl query(Mapi dbh, string q) { MapiHdl ret = null; if ((ret = mapi_query(dbh, toStringz(q) )) == null || mapi_error(dbh) != MOK) die(dbh, ret); return(ret); } void update(Mapi dbh, string q) { MapiHdl ret = query(dbh, q); if (mapi_close_handle(ret) != MOK) die(dbh, ret); } void main() { auto dbh = mapi_connect("localhost", 50000, "monetdb", "monetdb", "sql", "voc"); writeln("DB-connect"); update(dbh, "CREATE TABLE emp (name VARCHAR(20), age INT)"); writeln("create"); update(dbh, "INSERT INTO emp VALUES ('John', 23)"); update(dbh, "INSERT INTO emp VALUES ('Mary', 22)"); auto hdl = query(dbh, "SELECT * FROM emp"); while (mapi_fetch_row(hdl)) { auto name = mapi_fetch_field(hdl, 0); auto age = mapi_fetch_field(hdl, 1); printf("%s is %s\n", name, age); } } ``` Will try to make a complete binding available later...
Mar 22 2018
On Wednesday, 21 March 2018 at 16:22:45 UTC, Martin Tschierschke
wrote:
Is there an step by step introduction how to convert a C header
of an external lib into the right extern(C){} block?
A blog post or tutorial, or chapter in a D book? (I have those
from Packt Publishing)
(Especially I am trying to get this used with D:
Montetdb C-API
https://www.monetdb.org/Documentation/Manuals/SQLreference/Programming/MAPI
With:
https://github.com/snaga/monetdb/blob/master/clients/mapilib/mapi.h)
The page: https://dlang.org/spec/interfaceToC.html is known,
but not detailed enough for me.
The easiest thing to do is to write a wrapper in C. The wrapper
will include all necessary headers and provide some easy to use
functions that you can call from D. Of course, you'll need to use
a C compiler to compile it.
Anyway, this header looks very straightforwar, no particular
tricks with the preprocessor. It should be something like this
(untested, obviously):
import core.stdc.stdio : FILE;
enum
{
MAPI_AUTO = 0, /* automatic type detection */
MAPI_TINY = 1,
MAPI_UTINY = 2,
MAPI_SHORT = 3,
MAPI_USHORT = 4,
MAPI_INT = 5,
MAPI_UINT = 6,
MAPI_LONG = 7,
MAPI_ULONG = 8,
MAPI_LONGLONG = 9,
MAPI_ULONGLONG = 10,
MAPI_CHAR = 11,
MAPI_VARCHAR = 12,
MAPI_FLOAT = 13,
MAPI_DOUBLE = 14,
MAPI_DATE = 15,
MAPI_TIME = 16,
MAPI_DATETIME = 17,
MAPI_NUMERIC = 18,
}
enum int PLACEHOLDER = '?';
enum
{
MAPI_SEEK_SET = 0,
MAPI_SEEK_CUR = 1,
MAPI_SEEK_END = 2,
}
enum
{
MAPI_TRACE = 1,
MAPI_TRACE_LANG = 2,
}
alias MapiMsg = int;
enum
{
MOK = 0,
MERROR = -1,
MTIMEOUT = -2,
MMORE = -3,
MSERVER = -4,
}
enum
{
LANG_MAL = 0,
LANG_SQL = 2,
LANG_JAQL = 3,
}
/* prompts for MAPI protocol */
enum int PROMPTBEG = '\001'; /* start prompt bracket */
/* prompt: ready for new query */
const(char)* PROMPT1 = "\001\001\n".ptr;
/* prompt: more data needed */
const(char)* PROMTP2 = "\001\002\n".ptr;
/*
* The table field information is extracted from the table headers
* obtained from the server. This list may be extended in the
future.
* The type of both the 'param' and 'binding'
* variables refer to their underlying C-type. They are used for
* automatic type coercion between back-end and application.
*/
struct MapiStruct;
alias Mapi = MapiStruct*;
/* this definition is a straight copy from
sql/include/sql_query.h */
enum
{
Q_PARSE = 0,
Q_TABLE = 1,
Q_UPDATE = 2,
Q_SCHEMA = 3,
Q_TRANS = 4,
Q_PREPARE = 5,
Q_BLOCK = 6,
}
struct MapiStatement;
alias MapiHdl = MapiStatement*;
alias mapi_uint64 = ulong;
alias mapi_int64 = long;
/* three structures used for communicating date/time information
*/
/* these structs are deliberately compatible with the ODBC
versions
SQL_DATE_STRUCT, SQL_TIME_STRUCT, and SQL_TIMESTAMP_STRUCT */
/* used by MAPI_DATE */
struct MapiDate
{
short year;
ushort month;
ushort day;
}
/* used by MAPI_TIME */
struct MapiTime
{
ushort hour;
ushort minute;
ushort second;
}
/* used by MAPI_DATETIME */
struct MapiDateTime
{
short year;
ushort month;
ushort day;
ushort hour;
ushort minute;
ushort second;
uint fraction; /* in 1000 millionths of a second (10e-9) */
}
/* connection-oriented functions */
extern (C)
{
Mapi mapi_mapi(const char *host,
int port,
const char *username,
const char *password,
const char *lang,
const char *dbname);
// and so on...
}
Mar 21 2018
On Wednesday, 21 March 2018 at 18:42:43 UTC, nkm1 wrote:On Wednesday, 21 March 2018 at 16:22:45 UTC, Martin Tschierschke wrote:Thank you! Especially this was a missing link:[...]The easiest thing to do is to write a wrapper in C. The wrapper will include all necessary headers and provide some easy to use functions that you can call from D. Of course, you'll need to use a C compiler to compile it. Anyway, this header looks very straightforwar, no particular tricks with the preprocessor. It should be something like this (untested, obviously): [...]struct MapiStruct; alias Mapi = MapiStruct*;
Mar 22 2018
On Wednesday, 21 March 2018 at 16:22:45 UTC, Martin Tschierschke
wrote:
Is there an step by step introduction how to convert a C header
of an external lib into the right extern(C){} block?
In short, they should be binary compatible: where is a pointer on
C side, should be a pointer on D side, same for integer sizes,
data layout an calling conventions.
Mar 22 2018
On Wednesday, 21 March 2018 at 16:22:45 UTC, Martin Tschierschke
wrote:
Is there an step by step introduction how to convert a C header
of an external lib into the right extern(C){} block?
In addition to what others have said, I found the following
article on the D Wiki useful:
https://wiki.dlang.org/D_binding_for_C
Mar 22 2018
On Thursday, 22 March 2018 at 17:42:46 UTC, Paul Backus wrote:On Wednesday, 21 March 2018 at 16:22:45 UTC, Martin Tschierschke wrote:Thank you, this one is very good!Is there an step by step introduction how to convert a C header of an external lib into the right extern(C){} block?In addition to what others have said, I found the following article on the D Wiki useful: https://wiki.dlang.org/D_binding_for_C
Mar 22 2018
On Thursday, 22 March 2018 at 21:45:40 UTC, Martin Tschierschke wrote:On Thursday, 22 March 2018 at 17:42:46 UTC, Paul Backus wrote:If you have Learning D, chapter 9 is all about interface D with C.On Wednesday, 21 March 2018 at 16:22:45 UTC, Martin Tschierschke wrote:Thank you, this one is very good!Is there an step by step introduction how to convert a C header of an external lib into the right extern(C){} block?In addition to what others have said, I found the following article on the D Wiki useful: https://wiki.dlang.org/D_binding_for_C
Mar 22 2018
On Friday, 23 March 2018 at 01:12:58 UTC, Mike Parker wrote:On Thursday, 22 March 2018 at 21:45:40 UTC, Martin Tschierschke wrote:I will look at it! I have seen your hint already, you have mentioned it in the beginning of your blogpost. The discussion in an other thread [1] about direct integration of an C/C++ preprocessor into the D complier(s) is very interesting, I think this will push the adoption of the language, because you just can start immediately to use D as a replacement for C or C++. It is very fascinating to see how D is evolving all the time. Now I hope that with the survey and more donations the D Foundation get the ability to push this even more. [1] https://forum.dlang.org/post/hvanbsyrydsxpizltkca forum.dlang.orgOn Thursday, 22 March 2018 at 17:42:46 UTC, Paul Backus wrote:If you have Learning D, chapter 9 is all about interface D with C.On Wednesday, 21 March 2018 at 16:22:45 UTC, Martin Tschierschke wrote:Thank you, this one is very good!Is there an step by step introduction how to convert a C header of an external lib into the right extern(C){} block?In addition to what others have said, I found the following article on the D Wiki useful: https://wiki.dlang.org/D_binding_for_C
Mar 23 2018









ketmar <ketmar ketmar.no-ip.org> 