Jump to page: 1 2
Thread overview
__init unresolved external when using C library structs converted with dstep
Apr 14, 2020
Robert M. Münch
Apr 14, 2020
Robert M. Münch
Apr 15, 2020
Robert M. Münch
Apr 16, 2020
Robert M. Münch
Apr 16, 2020
Basile B.
Apr 17, 2020
Robert M. Münch
Apr 17, 2020
Robert M. Münch
April 14, 2020
I use a C libary and created D imports with dstep. It translates the C structs to D structs.

When I now use them, everything compiles fine but I get an unresolved external error:

WindowsApp1.obj : error LNK2019: unresolved external symbol "myCstruct.__init" (_D7myCStruct6__initZ) referenced in function _Dmain

Any idea what this is about and how to fix it? I'm wondering why D tries to find the __init function in the C library and not compile it from the import.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

April 14, 2020
On 4/14/20 1:51 PM, Robert M. Münch wrote:
> I use a C libary and created D imports with dstep. It translates the C structs to D structs.
> 
> When I now use them, everything compiles fine but I get an unresolved external error:
> 
> WindowsApp1.obj : error LNK2019: unresolved external symbol "myCstruct.__init" (_D7myCStruct6__initZ) referenced in function _Dmain
> 
> Any idea what this is about and how to fix it? I'm wondering why D tries to find the __init function in the C library and not compile it from the import.
> 

__init is not a function, it's a static member variable. It's the `intializer` property inside TypeInfo used for initialization.

Did you extern(C) the struct? Are you compiling the D file that contains the struct definition as well?

-Steve
April 14, 2020
On 2020-04-14 18:23:05 +0000, Steven Schveighoffer said:

> On 4/14/20 1:51 PM, Robert M. Münch wrote:
>> I use a C libary and created D imports with dstep. It translates the C structs to D structs.
>> 
>> When I now use them, everything compiles fine but I get an unresolved external error:
>> 
>> WindowsApp1.obj : error LNK2019: unresolved external symbol "myCstruct.__init" (_D7myCStruct6__initZ) referenced in function _Dmain
>> 
>> Any idea what this is about and how to fix it? I'm wondering why D tries to find the __init function in the C library and not compile it from the import.
>> 
> 
> __init is not a function, it's a static member variable. It's the `intializer` property inside TypeInfo used for initialization.

Ah, ok. That's why the problem went (temporarly) away when I did a: myCstruct a = {0,0}; for example?

> Did you extern(C) the struct?

Yes, everything is "extern(C) :" for the complete import files.

> Are you compiling the D file that contains the struct definition as well?

No. Is that the missing part?

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

April 14, 2020
On 4/14/20 2:29 PM, Robert M. Münch wrote:
> On 2020-04-14 18:23:05 +0000, Steven Schveighoffer said:
> 
>> On 4/14/20 1:51 PM, Robert M. Münch wrote:
>>> I use a C libary and created D imports with dstep. It translates the C structs to D structs.
>>>
>>> When I now use them, everything compiles fine but I get an unresolved external error:
>>>
>>> WindowsApp1.obj : error LNK2019: unresolved external symbol "myCstruct.__init" (_D7myCStruct6__initZ) referenced in function _Dmain
>>>
>>> Any idea what this is about and how to fix it? I'm wondering why D tries to find the __init function in the C library and not compile it from the import.
>>>
>>
>> __init is not a function, it's a static member variable. It's the `intializer` property inside TypeInfo used for initialization.
> 
> Ah, ok. That's why the problem went (temporarly) away when I did a: myCstruct a = {0,0}; for example?

I don't know what causes it to be emitted when. Sometimes it doesn't make a whole lot of sense to me.

> 
>> Did you extern(C) the struct?
> 
> Yes, everything is "extern(C) :" for the complete import files.

Then apparently the compiler still expects to have initializers even for foreign language structs. This is not a huge issue though, as the structs are ABI compatible even if compiled in D.

> 
>> Are you compiling the D file that contains the struct definition as well?
> 
> No. Is that the missing part?
> 

Probably. I think the compiler expects whatever is compiling the imported file to provide the symbol. If you aren't compiling it separately, then you need to include it in the compilation.

-Steve
April 15, 2020
On 2020-04-14 18:44:55 +0000, Steven Schveighoffer said:

> On 4/14/20 2:29 PM, Robert M. Münch wrote:
> 
>> Ah, ok. That's why the problem went (temporarly) away when I did a: myCstruct a = {0,0}; for example?
> 
> I don't know what causes it to be emitted when. Sometimes it doesn't make a whole lot of sense to me.

Hu... I wouldn't expect this to behave arbitrary...

>> Yes, everything is "extern(C) :" for the complete import files.
> 
> Then apparently the compiler still expects to have initializers even for foreign language structs.

Which surprised me, or more precise, I don't understand why these are not done implicitly using the D basic-type initializers.

>  This is not a huge issue though, as the structs are ABI compatible even if compiled in D.

Yes, fortunately.

>>> Are you compiling the D file that contains the struct definition as well?
>> 
>> No. Is that the missing part?
>> 
> 
> Probably. I think the compiler expects whatever is compiling the imported file to provide the symbol. If you aren't compiling it separately, then you need to include it in the compilation.

The C lib contains the smybols and I thought that the compiler just needs the imports to get an idea about the structures, types, etc. and later on the links resolves everything.

But, it works when I explicitly add the import source files to the VisualD project. Not sure what difference this makes, because the source can be compiled without any problems with/without those files added. But it seems that the linker now sees different things.

What's strange is, that for a dub project that uses the same imports, I didn't had to add them to the dub.json file. There, it just works without any problems.

All a bit strange and confusing...

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

April 15, 2020
On 4/15/20 8:38 AM, Robert M. Münch wrote:
> On 2020-04-14 18:44:55 +0000, Steven Schveighoffer said:
>> On 4/14/20 2:29 PM, Robert M. Münch wrote:
>>> No. Is that the missing part?
>>>
>>
>> Probably. I think the compiler expects whatever is compiling the imported file to provide the symbol. If you aren't compiling it separately, then you need to include it in the compilation.
> 
> The C lib contains the smybols and I thought that the compiler just needs the imports to get an idea about the structures, types, etc. and later on the links resolves everything.
> 
> But, it works when I explicitly add the import source files to the VisualD project. Not sure what difference this makes, because the source can be compiled without any problems with/without those files added. But it seems that the linker now sees different things.

The difference is you are telling the compiler that you it should generate any symbols for those types. If you just import them, then it's expecting something else to build those symbols.

You could also build a library that builds those symbols, and link in that library instead.

> 
> What's strange is, that for a dub project that uses the same imports, I didn't had to add them to the dub.json file. There, it just works without any problems.

dub builds all dependencies so this is like the library solution.

-Steve
April 16, 2020
On 2020-04-15 15:18:43 +0000, Steven Schveighoffer said:

> The difference is you are telling the compiler that it should generate any symbols for those types. If you just import them, then it's expecting something else to build those symbols.

Maybe I'm a bit confused, but that's quite different to a C compiler, right? If I include header and have a .lib things fit.

With D I have a .lib, I have the imports and still need the imports somehow compiled (included in project, or as a 2nd .lib) to make everything work. Do I understand that correct?

> You could also build a library that builds those symbols, and link in that library instead.

That would be the 2nd .lib approach than.

>> 
>> What's strange is, that for a dub project that uses the same imports, I didn't had to add them to the dub.json file. There, it just works without any problems.
> 
> dub builds all dependencies so this is like the library solution.

But I didn't include the library as a dub dependency. I just have the C/C++ compiled lib file and the D imports path for this lib.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

April 16, 2020
On 4/16/20 5:20 AM, Robert M. Münch wrote:
> On 2020-04-15 15:18:43 +0000, Steven Schveighoffer said:
> 
> 
> The difference is you are telling the compiler that it should generate any symbols for those types. If you just import them, then it's expecting something else to build those symbols.
> 
> 
> Maybe I'm a bit confused, but that's quite different to a C compiler, right? If I include header and have a .lib things fit.

C doesn't have initializer data for structs, because C doesn't initialize anything for you ;) So there is no data that needs to be defined somewhere, a C struct is just a compiler entity.

This is why I wasn't sure if extern(C) structs were required by D to have initializers. But it makes sense, because D is still going to initialize your C structs.

> With D I have a .lib, I have the imports and still need the imports somehow compiled (included in project, or as a 2nd .lib) to make everything work. Do I understand that correct?

if the .lib is compiled by C it does not include the initializer. But D needs it.

If the .lib is compiled by D, then it should have the initializer in it.

> 
> 
> You could also build a library that builds those symbols, and link in that library instead.
> 
> 
> That would be the 2nd .lib approach than.

Yes. That is why D wrapper bindings for C libraries need their own library.

> 
> What's strange is, that for a dub project that uses the same imports, I didn't had to add them to the dub.json file. There, it just works without any problems.
> 
> 
> dub builds all dependencies so this is like the library solution.
> 
> 
> But I didn't include the library as a dub dependency. I just have the C/C++ compiled lib file and the D imports path for this lib.

Perhaps dub is being over-zealous when given imports. Maybe instead of importing using -I, it's compiling the import directly.

Check the command line that it's using by doing dub -v.

-Steve
April 16, 2020
On Tuesday, 14 April 2020 at 17:51:58 UTC, Robert M. Münch wrote:
> I use a C libary and created D imports with dstep. It translates the C structs to D structs.
>
> When I now use them, everything compiles fine but I get an unresolved external error:
>
> WindowsApp1.obj : error LNK2019: unresolved external symbol "myCstruct.__init" (_D7myCStruct6__initZ) referenced in function _Dmain
>
> Any idea what this is about and how to fix it? I'm wondering why D tries to find the __init function in the C library and not compile it from the import.

One way to prevent the problem is to do void initialization each time you declare a variable of this type.
April 17, 2020
On 2020-04-16 18:33:51 +0000, Basile B. said:

> On Tuesday, 14 April 2020 at 17:51:58 UTC, Robert M. Münch wrote:
>> I use a C libary and created D imports with dstep. It translates the C structs to D structs.
>> 
>> When I now use them, everything compiles fine but I get an unresolved external error:
>> 
>> WindowsApp1.obj : error LNK2019: unresolved external symbol "myCstruct.__init" (_D7myCStruct6__initZ) referenced in function _Dmain
>> 
>> Any idea what this is about and how to fix it? I'm wondering why D tries to find the __init function in the C library and not compile it from the import.
> 
> One way to prevent the problem is to do void initialization each time you declare a variable of this type.

How would that look like?

myStruct ms = void; // ???

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

« First   ‹ Prev
1 2