www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - __init unresolved external when using C library structs converted with dstep

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Apr 14 2020
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Apr 14 2020
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Apr 14 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Apr 14 2020
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Apr 15 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Apr 15 2020
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Apr 16 2020
parent Steven Schveighoffer <schveiguy gmail.com> writes:
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
Apr 16 2020
prev sibling parent reply Basile B. <b2.temp gmx.com> writes:
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.
Apr 16 2020
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Apr 17 2020
parent reply Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
On Friday, 17 April 2020 at 08:59:41 UTC, Robert M. Münch wrote:
 How would that look like?

 myStruct ms = void; // ???
Exactly.
Apr 17 2020
parent =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2020-04-17 09:06:44 +0000, Dominikus Dittes Scherkl said:

 On Friday, 17 April 2020 at 08:59:41 UTC, Robert M. Münch wrote:
 How would that look like?
 
 myStruct ms = void; // ???
Exactly.
Cool... never saw this / thought about it... will remember it, hopefully. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Apr 17 2020