Generating struct members from c structs

2020-07-01 Thread Anthony via Digitalmars-d-learn
When doing interop with a c library, is there a way to 
automatically generate the fields that are needed for a struct?


For example, when interfacing with the lwan c library:

// lwan.h
struct lwan {
struct lwan_trie url_map_trie;
struct lwan_connection *conns;
struct lwan_strbuf headers;

struct {
pthread_barrier_t barrier;
struct lwan_thread *threads;
unsigned int max_fd;
unsigned int count;
} thread;

struct lwan_config config;
struct coro_switcher switcher;

int main_socket;

unsigned int n_cpus;
};

module lwan;

extern (C) {
struct lwan {
  ... // <<< How do I populate this without having to write 
all the sub structs?

};
void lwan_init(lwan* l);
void lwan_shutdown(lwan* l);
}

import lwan;

void main() {
  lwan l; //This is currently not allocating enough memory
  lwan_init();
  lwan_shutdown();
}

How do I populate the lwan struct without having to write all the 
sub structs?


I'm thinking that maybe it'll be best to create a wrapper c 
function that initializes the lwan struct and returns a pointer.


That way I don't have to declare any fields.

extern (C) {
struct lwan;

lwan* lwan_make(); //wrapper function (perhaps in wrapper.c)
void lwan_cleanup(lwan* l); //wrapper function

void lwan_init(lwan* l);
void lwan_shutdown(lwan* l);
}

Is there an easier way though?



Re: Program exited with code -11 when calling

2020-07-01 Thread Anthony via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 05:47:16 UTC, Anthony wrote:

On Wednesday, 1 July 2020 at 05:33:48 UTC, H. S. Teoh wrote:
On Wed, Jul 01, 2020 at 05:04:28AM +, Anthony via 
Digitalmars-d-learn wrote: [...]

auto str_utf8 = str.toUTF8();
bson_error_t error

auto bson = bson_new_from_json(cast(const 
uint8_t*)str_utf8.ptr, -1,

);


I get a "Program exited with code -11" message.
Does anyone know what I'm doing wrong?


D strings are generally not null-terminated (except for 
literals). Before passing them to a C function you need to add 
a trailing null. Try using std.conv.toStringz instead of 
casting the pointer yourself.



T


Thanks H. S. Teoh.
Hmm, still same result though.


import std.string;

auto str = toStringz("{\"a\":1}");

bson_error_t error;

bson_new_from_json(str, -1, );




extern(C) {
...
bson_t* bson_new_from_json(const char* data, long len, 
bson_error_t* error);

}


Noob mistake:
I declared an array that should be of fixed size.

struct bson_error_t {

char[] message;
};

Should be:

struct bson_error_t {

char[504] message;
};

:/


Re: Program exited with code -11 when calling

2020-06-30 Thread Anthony via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 05:33:48 UTC, H. S. Teoh wrote:
On Wed, Jul 01, 2020 at 05:04:28AM +, Anthony via 
Digitalmars-d-learn wrote: [...]

auto str_utf8 = str.toUTF8();
bson_error_t error

auto bson = bson_new_from_json(cast(const 
uint8_t*)str_utf8.ptr, -1,

);


I get a "Program exited with code -11" message.
Does anyone know what I'm doing wrong?


D strings are generally not null-terminated (except for 
literals). Before passing them to a C function you need to add 
a trailing null. Try using std.conv.toStringz instead of 
casting the pointer yourself.



T


Thanks H. S. Teoh.
Hmm, still same result though.


import std.string;

auto str = toStringz("{\"a\":1}");

bson_error_t error;

bson_new_from_json(str, -1, );




extern(C) {
...
bson_t* bson_new_from_json(const char* data, long len, 
bson_error_t* error);

}


Re: Linking D with C structs

2020-06-30 Thread Anthony via Digitalmars-d-learn

On Monday, 29 June 2020 at 10:44:16 UTC, kinke wrote:

On Monday, 29 June 2020 at 06:29:38 UTC, Anthony wrote:

What does "__initZ" refer to?
Does this refer to automatic initialization like "this()"?


Almost, it's the static initializer for that struct, which is 
omitted because you apparently don't compile/link the module 
containing the struct declaration. Initialize the char array 
with zeros (= 0) to make the struct fully zero-initialized, 
preventing the need for that symbol. chars in D are initialized 
with 0xFF, unlike byte and ubyte.


Thanks for this!

What do you mean by "which is omitted because you apparently 
don't compile/link the module containing the struct declaration"?


Is there a link step that I'm missing that will make things 
easier for me?
Is there a way to have D automatically get the struct from the c 
files directly?




Re: Program exited with code -11 when calling

2020-06-30 Thread Anthony via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 05:09:47 UTC, Cym13 wrote:

On Wednesday, 1 July 2020 at 05:04:28 UTC, Anthony wrote:

I'm trying to convert this c function:

bson_t *bson_new_from_json (const uint8_t *data, ssize_t len, 
bson_error_t *error);



Into a D function. This is my attempt:
extern(C) {
struct bson_t;
struct bson_error_t;

bson_t* bson_new_from_json(const uint8_t* data, long len, 
bson_error_t* error);

}

However when I try it, for example:

auto str_utf8 = str.toUTF8();
bson_error_t error

auto bson = bson_new_from_json(cast(const 
uint8_t*)str_utf8.ptr, -1, );



I get a "Program exited with code -11" message.
Does anyone know what I'm doing wrong?

Thanks


I don't know the exact function you are trying to use, but -11 
means "segmentation fault" on linux. This means that your 
program is trying to read or write a memory location that it is 
not supposed to. This typically happens during buffer overflows 
and similar memory corruption bugs.


One thing that jumps to me is the -1 in your call instead of 
the length. Without knowing the C function's implementation I 
would expect it to mean either "read before the array" which 
would be a buffer overflow or to have the special meaning of 
"deduce the string size yourself". In that last case I would 
expect bson_new_from_json to expect a NUL-terminated array, but 
I don't know if your UTF8 array is NUL-terminated.



Thanks for getting back to me.

Yeah I figured it was a segmentation fault, however, I don't know 
exactly how to pinpoint where this is happening. I'm wondering if 
there's anything wrong with how I'm casting the data since 
everything is self contained (assuming bson_new_from_json is 
correct since it works using c directly).


void foo() {
import std.utf;
import core.stdc.stdint;

auto str_utf8 = "{\"a\":1}";
bson_error_t error;

bson_new_from_json(cast(uint8_t*)str_utf8, 
(cast(uint8_t[])str_utf8).length, );

}



Re -1 in the call: Apparently it uses strlen() to deduce the 
size. However, I tried explicitly state the array length but had 
no luck.





Program exited with code -11 when calling

2020-06-30 Thread Anthony via Digitalmars-d-learn

I'm trying to convert this c function:

bson_t *bson_new_from_json (const uint8_t *data, ssize_t len, 
bson_error_t *error);



Into a D function. This is my attempt:
extern(C) {
struct bson_t;
struct bson_error_t;

bson_t* bson_new_from_json(const uint8_t* data, long len, 
bson_error_t* error);

}

However when I try it, for example:

auto str_utf8 = str.toUTF8();
bson_error_t error

auto bson = bson_new_from_json(cast(const uint8_t*)str_utf8.ptr, 
-1, );



I get a "Program exited with code -11" message.
Does anyone know what I'm doing wrong?

Thanks



Linking D with C structs

2020-06-29 Thread Anthony via Digitalmars-d-learn

Hello,


I'm trying to hand write some bindings to mongo-c-driver. (For 
learning purposes and to get the latest bindings).


My binding code to convert  to mongoc/mongoc.d 
is:


= c interop file 
module mongoc/mongoc.d;
import core.stdc.stdint;

extern (c) {
struct {
uint domain;
uint code;
char[504] message; //when this exists, the code does not 
compile

}
}
===

= build script 

export 
LD_LIBRARY_PATH=mongo-c-driver/cmake-build/src/libmongoc:mongo-c-driver/cmake-build/src/libbson:$LD_LIBRARY_PATH


dmd hello_mongo.d \
-I=mongo-c-driver/src/libmongoc/src/ \
-I=mongo-c-driver/src/libbson/src/ \
-I=mongo-c-driver/cmake-build/src/libbson/src/bson/ \
-I=mongo-c-driver/cmake-build/src/libmongoc/src/mongoc \
-L=-Lmongo-c-driver/cmake-build/src/libmongoc \
-L=-Lmongo-c-driver/cmake-build/src/libbson \
-L=-lmongoc-1.0 \
-L=-lbson-1.0 \

./hello_mongo



However, when I add the message field in the struct, I cannot 
compile the code:


ld: hello_mongo.o: in function `_Dmain':
hello_mongo.d:(.text._Dmain[_Dmain]+0x1a): undefined reference to 
`_D6mongoc6mongoc13_bson_error_t6__initZ'



What does "__initZ" refer to?
Does this refer to automatic initialization like "this()"?