Thread overview
static init c struct with array filed
Mar 16, 2022
test
Mar 16, 2022
user1234
Mar 16, 2022
Era Scarecrow
Mar 16, 2022
user1234
Mar 16, 2022
Ali Çehreli
Mar 17, 2022
Mike Parker
Mar 17, 2022
Adam Ruppe
March 16, 2022
struct Test {
    int32_t a;
}
struct Test2 {
    int32_t a;
    Test arr[];
}

I need static const init Test2, then pass it to c library late(third library, can not change the type def).

I am not sure how to do it in D.

March 16, 2022

On Wednesday, 16 March 2022 at 07:27:06 UTC, test wrote:

>
struct Test {
    int32_t a;
}
struct Test2 {
    int32_t a;
    Test arr[];
}

I need static const init Test2, then pass it to c library late(third library, can not change the type def).

I am not sure how to do it in D.

extern(C) struct Test {
    int a;
}

extern(C) struct Test2 {
     int a;
     Test* arr;
}


static const Test2 t2 = Test2(2, null);

void main(){
   to_c_library(&t2);
   to_c_library(new Test2(2, null));
   Test2 local;
   to_c_library(&local);
}

assuming the c library takes by reference

March 16, 2022

On Wednesday, 16 March 2022 at 11:27:20 UTC, user1234 wrote:

>

assuming the c library takes by reference

My experience all arrays are effectively just pointers, and the brackets/length is only really applicable to stack allocated fixed length allocations. In my own C projects i always used pointers to pass arrays around.

There's also static construction, though i don't see how that improves anything

https://dlang.org/spec/module.html#staticorder

March 16, 2022

On Wednesday, 16 March 2022 at 14:42:02 UTC, Era Scarecrow wrote:

>

On Wednesday, 16 March 2022 at 11:27:20 UTC, user1234 wrote:

>

assuming the c library takes by reference

My experience all arrays are effectively just pointers

I meant the function that takes the Test2 as parameter, but to be honest I dont get exactly what does OP want actually... that's true that passing a Test2 is somewhat strange as there's no info for the array length.

March 16, 2022
On 3/16/22 10:03, user1234 wrote:
> On Wednesday, 16 March 2022 at 14:42:02 UTC, Era Scarecrow wrote:
>> On Wednesday, 16 March 2022 at 11:27:20 UTC, user1234 wrote:
>>> assuming the c library takes by reference
>>
>>  My experience all arrays are effectively just pointers
>
> I meant the function that takes the Test2 as parameter, but to be honest
> I dont get exactly what does OP want actually...

They want to pass Test2 to C and be able to use it. D ABI defines arrays (slices) as a pair of size_t and a pointer:

  https://dlang.org/spec/abi.html#arrays

I haven't passed such a struct to C but I believe the equivalent C struct can assume there are the following members in place of the array:

struct Test2 {
    int32_t a;
    size_t length;
    Test * ptr;
}

However, the lifetime of ptr must be ensured on the D side because utless there is a reference to it on the D side, the GC can free the memory at any time and C side may access invalid memory.

That is explained here:

  https://dlang.org/spec/interfaceToC.html#storage_allocation

Ali

March 17, 2022

On Wednesday, 16 March 2022 at 07:27:06 UTC, test wrote:

>
struct Test {
    int32_t a;
}
struct Test2 {
    int32_t a;
    Test arr[];
}

I need static const init Test2, then pass it to c library late(third library, can not change the type def).

Any time you see a '[]' in C, the equivalent declaration in D has to be a pointer. Like Ali said, D's arrays are a pointer and length pair, so declaring the declaration of the arr member will not match the declaration on the C side.

Since you say you can't change the declaration on the C side, user1234's answer is the direction you want to go (though you don't need the extern(C) on the structs).

March 17, 2022

On Thursday, 17 March 2022 at 00:16:39 UTC, Mike Parker wrote:

>

On Wednesday, 16 March 2022 at 07:27:06 UTC, test wrote:

>
struct Test {
    int32_t a;
}
struct Test2 {
    int32_t a;
    Test arr[];
}

I need static const init Test2, then pass it to c library late(third library, can not change the type def).

Any time you see a '[]' in C, the equivalent declaration in D has to be a pointer.

Not always with structs....... if it has a fixed size or an initializer in C, then you need to match the size in D.

Otherwise yeah use the pointer.