www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Use C struct declaration without knowing definition

reply Ben Ogles <benjaminogles gmail.com> writes:
Is there a way to use a C header that contains a struct 
declaration but no definition?

For example, the C header may contain:

typedef struct some_type_s some_type;

Which is only fully defined in the implementing C file:

struct some_type_s { ... };

I am trying to wrap the header in D:

extern(C)
{
   struct some_type_s;
   alias some_type = some_type_s;
}

And then use it in another D file:

some_type s;

But dmd does not know the size of the struct so it can't compile. 
Is there a work around to this other than moving the struct 
definition into the C header file?
Jul 24 2019
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 07/24/2019 05:35 PM, Ben Ogles wrote:
 Is there a way to use a C header that contains a struct declaration but
 no definition?

 For example, the C header may contain:

 typedef struct some_type_s some_type;

 Which is only fully defined in the implementing C file:

 struct some_type_s { ... };
And that type is traded as pointer to some_type on the C API, right? Usually there is a factory method that returns a pointer to a dynamically allocated object.
 I am trying to wrap the header in D:

 extern(C)
 {
    struct some_type_s;
    alias some_type = some_type_s;
 }

 And then use it in another D file:

 some_type s;

 But dmd does not know the size of the struct so it can't compile. Is
 there a work around to this other than moving the struct definition into
 the C header file?
Indeed. The only option is to use some_type* on the D API as well: extern(C) { struct S; S* C_API_allocate(); void C_API(const(S) *); } // D API void foo(S* s) { C_API(s); } void main() { auto s = C_API_allocate(); foo(s); } Note: That program fails to link because C API functions are missing definitions. You can wrap the pointer i a D struct and dispatch member function calls to the C API. Ali
Jul 24 2019
parent Ben Ogles <benjaminogles gmail.com> writes:
On Thursday, 25 July 2019 at 01:08:48 UTC, Ali Çehreli wrote:
 And that type is traded as pointer to some_type on the C API, 
 right? Usually there is a factory method that returns a pointer 
 to a dynamically allocated object.
Correct, there is a function prototype that returns a dynamically allocated instance of the struct.
 Indeed. The only option is to use some_type* on the D API as 
 well:

 extern(C) {
   struct S;
   S* C_API_allocate();
   void C_API(const(S) *);
 }

 // D API
 void foo(S* s)  {
   C_API(s);
 }

 void main() {
   auto s = C_API_allocate();
   foo(s);
 }
This makes sense. I can only deal with pointers to dynamically allocated instances of the struct since there is no way to know the size of the struct at compile time. Now that I think about it, this would be the case whether or not I was using D at all. Thanks for your help!
Jul 24 2019