View mode: basic / threaded / horizontal-split · Log in · Help
November 19, 2005
linking C++ to D on windows troubles...
What is the correct way to link a C++ library to D under windows? I can 
get it to work under linux, but on windows I get undefined symbols.

Here's what I've tried so far...


1) Used implib to convert a DLL to a .lib file with the command 'implib 
MyLib.lib MyLib.dll' For some reason, the linker still can't find the 
symbols for the DLL file.

2) in my C++ code, I use

extern "C" {
  func();
}

should I be using extern "Windows" instead? I googled to see if there 
was one but I couldn't find anything about it.

and in my D code I use...

extern(C) or extern(Windows) (i've tried both)
{
  func();
}


I also use dmc to compile my cpp code, and create a lib with 'lib -c 
mylib.lib a.obj b.obj c.obj' For some reason the linker doesn't 
recognize the symbols inside of a.obj and b.obj and c.obj so I just end 
up passing a.obj and b.obj and c.obj directly to the compiler, which 
then recognizes objects and compains about all the ones missing from the 
DLL i'm trying to use.


3) I compile it all with .. build test.d -Lmyimplib.lib -Lmycpplib.lib

Is this not the correct way to link lib files to D? Because it doesn't 
seem to be working for me.

Also, are D's .lib files and ming32's .a files compatible? I get the 
feeling they are not, otherwise I would just use my RakNet.a file 
compiled with ming32.

I guess my main problem is hooking the DLL up to my D application :-/

Thanks
~ Clay
November 20, 2005
Re: linking C++ to D on windows troubles...
"clayasaurus" <clayasaurus@gmail.com> wrote in message 
news:dlo8gc$19vi$1@digitaldaemon.com...
> What is the correct way to link a C++ library to D under windows? I can 
> get it to work under linux, but on windows I get undefined symbols.
>
> Here's what I've tried so far...
>
>
> 1) Used implib to convert a DLL to a .lib file with the command 'implib 
> MyLib.lib MyLib.dll' For some reason, the linker still can't find the 
> symbols for the DLL file.
>
> 2) in my C++ code, I use
>
> extern "C" {
>   func();
> }
>
> should I be using extern "Windows" instead? I googled to see if there was 
> one but I couldn't find anything about it.
>
> and in my D code I use...
>
> extern(C) or extern(Windows) (i've tried both)
> {
>   func();
> }
>
>
> I also use dmc to compile my cpp code, and create a lib with 'lib -c 
> mylib.lib a.obj b.obj c.obj' For some reason the linker doesn't recognize 
> the symbols inside of a.obj and b.obj and c.obj so I just end up passing 
> a.obj and b.obj and c.obj directly to the compiler, which then recognizes 
> objects and compains about all the ones missing from the DLL i'm trying to 
> use.
>
>
> 3) I compile it all with .. build test.d -Lmyimplib.lib -Lmycpplib.lib
>
> Is this not the correct way to link lib files to D? Because it doesn't 
> seem to be working for me.
>
> Also, are D's .lib files and ming32's .a files compatible? I get the 
> feeling they are not, otherwise I would just use my RakNet.a file compiled 
> with ming32.
>
> I guess my main problem is hooking the DLL up to my D application :-/
>
> Thanks
> ~ Clay

Sounds like your DLL functions aren't getting exported. You need to use 
dllexport on functions you wish to export, like this:

#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllexport) void func();

#ifdef __cplusplus
}
#endif
November 20, 2005
Re: linking C++ to D on windows troubles...
John C wrote:
> "clayasaurus" <clayasaurus@gmail.com> wrote in message 
> news:dlo8gc$19vi$1@digitaldaemon.com...
> 
>>What is the correct way to link a C++ library to D under windows? I can 
>>get it to work under linux, but on windows I get undefined symbols.
>>
>>Here's what I've tried so far...
>>
>>
>>1) Used implib to convert a DLL to a .lib file with the command 'implib 
>>MyLib.lib MyLib.dll' For some reason, the linker still can't find the 
>>symbols for the DLL file.
>>
>>2) in my C++ code, I use
>>
>>extern "C" {
>>  func();
>>}
>>
>>should I be using extern "Windows" instead? I googled to see if there was 
>>one but I couldn't find anything about it.
>>
>>and in my D code I use...
>>
>>extern(C) or extern(Windows) (i've tried both)
>>{
>>  func();
>>}
>>
>>
>>I also use dmc to compile my cpp code, and create a lib with 'lib -c 
>>mylib.lib a.obj b.obj c.obj' For some reason the linker doesn't recognize 
>>the symbols inside of a.obj and b.obj and c.obj so I just end up passing 
>>a.obj and b.obj and c.obj directly to the compiler, which then recognizes 
>>objects and compains about all the ones missing from the DLL i'm trying to 
>>use.
>>
>>
>>3) I compile it all with .. build test.d -Lmyimplib.lib -Lmycpplib.lib
>>
>>Is this not the correct way to link lib files to D? Because it doesn't 
>>seem to be working for me.
>>
>>Also, are D's .lib files and ming32's .a files compatible? I get the 
>>feeling they are not, otherwise I would just use my RakNet.a file compiled 
>>with ming32.
>>
>>I guess my main problem is hooking the DLL up to my D application :-/
>>
>>Thanks
>>~ Clay
> 
> 
> Sounds like your DLL functions aren't getting exported. You need to use 
> dllexport on functions you wish to export, like this:
> 
> #ifdef __cplusplus
> extern "C" {
> #endif
> 
> __declspec(dllexport) void func();
> 
> #ifdef __cplusplus
> }
> #endif
> 
> 

I mentioned that using the -Lmylib.lib didn't find the symbols for the 
compiler, but adding each obj seperately with 'a.obj b.obj c.obj' 
worked. Any idea what could cause this?

Thanks.
November 20, 2005
Re: linking C++ to D on windows troubles...
clayasaurus wrote:
> John C wrote:
> 
>> "clayasaurus" <clayasaurus@gmail.com> wrote in message 
>> news:dlo8gc$19vi$1@digitaldaemon.com...
>>
>>> What is the correct way to link a C++ library to D under windows? I 
>>> can get it to work under linux, but on windows I get undefined symbols.
>>>
>>> Here's what I've tried so far...
>>>
>>>
>>> 1) Used implib to convert a DLL to a .lib file with the command 
>>> 'implib MyLib.lib MyLib.dll' For some reason, the linker still can't 
>>> find the symbols for the DLL file.
>>>
>>> 2) in my C++ code, I use
>>>
>>> extern "C" {
>>>  func();
>>> }
>>>
>>> should I be using extern "Windows" instead? I googled to see if there 
>>> was one but I couldn't find anything about it.
>>>
>>> and in my D code I use...
>>>
>>> extern(C) or extern(Windows) (i've tried both)
>>> {
>>>  func();
>>> }
>>>
>>>
>>> I also use dmc to compile my cpp code, and create a lib with 'lib -c 
>>> mylib.lib a.obj b.obj c.obj' For some reason the linker doesn't 
>>> recognize the symbols inside of a.obj and b.obj and c.obj so I just 
>>> end up passing a.obj and b.obj and c.obj directly to the compiler, 
>>> which then recognizes objects and compains about all the ones missing 
>>> from the DLL i'm trying to use.
>>>
>>>
>>> 3) I compile it all with .. build test.d -Lmyimplib.lib -Lmycpplib.lib
>>>
>>> Is this not the correct way to link lib files to D? Because it 
>>> doesn't seem to be working for me.
>>>
>>> Also, are D's .lib files and ming32's .a files compatible? I get the 
>>> feeling they are not, otherwise I would just use my RakNet.a file 
>>> compiled with ming32.
>>>
>>> I guess my main problem is hooking the DLL up to my D application :-/
>>>
>>> Thanks
>>> ~ Clay
>>
>>
>>
>> Sounds like your DLL functions aren't getting exported. You need to 
>> use dllexport on functions you wish to export, like this:
>>
>> #ifdef __cplusplus
>> extern "C" {
>> #endif
>>
>> __declspec(dllexport) void func();
>>
>> #ifdef __cplusplus
>> }
>> #endif
>>
>>
> 
> I mentioned that using the -Lmylib.lib didn't find the symbols for the 
> compiler, but adding each obj seperately with 'a.obj b.obj c.obj' 
> worked. Any idea what could cause this?
> 
> Thanks.
> 
> 

Forgot to mention, I found a static lib that I could use instead of a 
DLL. However, if I can't get my own static libs to work then I'm stuck.
November 20, 2005
Re: Detailed Error description for -L linker
C:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug -Lrakglue.lib 
-LRakNetLibStatic.lib
C:\dmd\bin\..\..\dm\bin\link.exe 
chat+raknet\server+raknet\raknet+raknet\client+raknet\packetenumerations+raknet\packetpriority+raknet\networktypes,chat.exe,,user32+kernel32,chat.def/co/noirakglue.libRakNetLibStatic.lib;

OPTLINK (R) for Win32  Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

OPTLINK : Warning 9: Unknown Option : NOIRAKGLUE.LIBRAKNETLIBSTATIC.LIB
C:\dmd\bin\..\lib\phobos.lib(ti_double)  Offset 19FC5H Record Type 0091
 Error 1: Previous Definition Different : __init_10TypeInfo_d
C:\dmd\bin\..\lib\phobos.lib(ti_double)  Offset 19FDFH Record Type 0091
 Error 1: Previous Definition Different : __Class_10TypeInfo_d
C:\dmd\bin\..\lib\phobos.lib(ti_double)  Offset 19FF8H Record Type 0091
 Error 1: Previous Definition Different : __vtbl_10TypeInfo_d
chat.obj(chat)
 Error 42: Symbol Undefined _rakClientInterface_REG_AS_RPC@8
chat.obj(chat)
 etc. list of undefined symbols...

:-/ It works if I just use the .obj files, but I need it to work with .lib

clayasaurus wrote:
> clayasaurus wrote:
> 
>> John C wrote:
>>
>>> "clayasaurus" <clayasaurus@gmail.com> wrote in message 
>>> news:dlo8gc$19vi$1@digitaldaemon.com...
>>>
>>>> What is the correct way to link a C++ library to D under windows? I 
>>>> can get it to work under linux, but on windows I get undefined symbols.
>>>>
>>>> Here's what I've tried so far...
>>>>
>>>>
>>>> 1) Used implib to convert a DLL to a .lib file with the command 
>>>> 'implib MyLib.lib MyLib.dll' For some reason, the linker still can't 
>>>> find the symbols for the DLL file.
>>>>
>>>> 2) in my C++ code, I use
>>>>
>>>> extern "C" {
>>>>  func();
>>>> }
>>>>
>>>> should I be using extern "Windows" instead? I googled to see if 
>>>> there was one but I couldn't find anything about it.
>>>>
>>>> and in my D code I use...
>>>>
>>>> extern(C) or extern(Windows) (i've tried both)
>>>> {
>>>>  func();
>>>> }
>>>>
>>>>
>>>> I also use dmc to compile my cpp code, and create a lib with 'lib -c 
>>>> mylib.lib a.obj b.obj c.obj' For some reason the linker doesn't 
>>>> recognize the symbols inside of a.obj and b.obj and c.obj so I just 
>>>> end up passing a.obj and b.obj and c.obj directly to the compiler, 
>>>> which then recognizes objects and compains about all the ones 
>>>> missing from the DLL i'm trying to use.
>>>>
>>>>
>>>> 3) I compile it all with .. build test.d -Lmyimplib.lib -Lmycpplib.lib
>>>>
>>>> Is this not the correct way to link lib files to D? Because it 
>>>> doesn't seem to be working for me.
>>>>
>>>> Also, are D's .lib files and ming32's .a files compatible? I get the 
>>>> feeling they are not, otherwise I would just use my RakNet.a file 
>>>> compiled with ming32.
>>>>
>>>> I guess my main problem is hooking the DLL up to my D application :-/
>>>>
>>>> Thanks
>>>> ~ Clay
>>>
>>>
>>>
>>>
>>> Sounds like your DLL functions aren't getting exported. You need to 
>>> use dllexport on functions you wish to export, like this:
>>>
>>> #ifdef __cplusplus
>>> extern "C" {
>>> #endif
>>>
>>> __declspec(dllexport) void func();
>>>
>>> #ifdef __cplusplus
>>> }
>>> #endif
>>>
>>>
>>
>> I mentioned that using the -Lmylib.lib didn't find the symbols for the 
>> compiler, but adding each obj seperately with 'a.obj b.obj c.obj' 
>> worked. Any idea what could cause this?
>>
>> Thanks.
>>
>>
> 
> Forgot to mention, I found a static lib that I could use instead of a 
> DLL. However, if I can't get my own static libs to work then I'm stuck.
> 
> 
>
November 20, 2005
Re: Detailed Error description for -L linker
clayasaurus wrote:
> C:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug -Lrakglue.lib 
> -LRakNetLibStatic.lib
> C:\dmd\bin\..\..\dm\bin\link.exe 
> chat+raknet\server+raknet\raknet+raknet\client+raknet\packetenumerations+raknet\packetpriority+raknet\networktypes,chat.exe,,user32+kernel32,chat.def/co/noirakglue.libRakNetLibStatic.lib; 
> 
> 
> OPTLINK (R) for Win32  Release 7.50B1
> Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved
> 


Why is buiild giving this warning:

> OPTLINK : Warning 9: Unknown Option : NOIRAKGLUE.LIBRAKNETLIBSTATIC.LIB

For some reason, the build command line is being processed incorrectly 
by optlink.  Why are you using -L switch on the command line?  It 
appears that the -L flag passes its contents on to optlink via dmd.  In 
this case -L is supposed to accept "linker flags", not  a library name 
(unless I'm mistaken).  Why don't you just include the library name 
without the switch decorating it?

Like so:

c:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug rakglue.lib

> C:\dmd\bin\..\lib\phobos.lib(ti_double)  Offset 19FC5H Record Type 0091
>  Error 1: Previous Definition Different : __init_10TypeInfo_d
> C:\dmd\bin\..\lib\phobos.lib(ti_double)  Offset 19FDFH Record Type 0091
>  Error 1: Previous Definition Different : __Class_10TypeInfo_d
> C:\dmd\bin\..\lib\phobos.lib(ti_double)  Offset 19FF8H Record Type 0091
>  Error 1: Previous Definition Different : __vtbl_10TypeInfo_d
> chat.obj(chat)
>  Error 42: Symbol Undefined _rakClientInterface_REG_AS_RPC@8
> chat.obj(chat)
>  etc. list of undefined symbols...
> 
> :-/ It works if I just use the .obj files, but I need it to work with .lib
>

The above should disappear as soon as the *.lib files are correctly 
submitted to the link command line.  It should work just like the object 
files.  It's that nasty -L switch that seems to messing you up.

-JJR
November 20, 2005
Re: Detailed Error description for -L linker
John Reimer wrote:

> Like so:
> 
> c:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug rakglue.lib
> 

Of course I meant:

C:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug rakglue.lib 
RakNetLibStatic.lib
November 20, 2005
Re: Detailed Error description for -L linker
On Sun, 20 Nov 2005 01:46:28 -0500, clayasaurus wrote:

> C:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug -Lrakglue.lib 

[snip]
>>> I mentioned that using the -Lmylib.lib didn't find the symbols for the 
>>> compiler, but adding each obj seperately with 'a.obj b.obj c.obj' 
>>> worked. Any idea what could cause this?
[snip]

The -L switch is used to pass 'flags' to the linker and not library names.

I assume that because you are on Windows that this is using optlink as the
linker. The only way to pass library names to optlink is by placing them on
the command line as plain file names, because optlink does not accept
library names as flags/switches. Instead optlink only accepts library names
as positional command line parameters, and dmd formats the command line for
optlink. 

(By the way, the next Build will allow an alternative to this, however I've
only coded the Windows edition so far and the linux stuff is still
work-in-progress).

-- 
Derek Parnell
Melbourne, Australia
21/11/2005 6:34:34 AM
November 20, 2005
Re: Thanks. Issues still left.
John Reimer wrote:
> John Reimer wrote:
> 
>> Like so:
>>
>> c:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug rakglue.lib
>>
> 
> Of course I meant:
> 
> C:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug rakglue.lib 
> RakNetLibStatic.lib
> 

Ahh thanks. I'm used to using the -Llib command because that is how it 
works under linux.

I also realized that my static raknet lib is in the wrong format (coff i 
think), and raknet doesn't support the dmc compiler (I put a request in 
their forum), so I'm back to using implib on RakNet.dll.

There is also something funky with the librarian, because when I link 
with the rakglue.lib it says one of my symbols is undefined, however 
when I link with *.obj it doesn't complain, but then then proceeds to 
tell me it can't find all the symbols it needs from my implib RakNet.lib 
file.

I know my problems could be fixed if...

1) RakNet supported DMC compiler, so I could create RakNet.lib in DMC's 
format

2) Pay $15 for coff2omf which may or may not work

3) A native version of GDC on windows so I can use GCC's linker, cygwin 
won't work because I need access to windows stuff as cygwin doesn't 
define version(Windows) and it causes problems with import 
std.c.windows.windows assertion failure.

4) either I'm using implib wrong (implib RakNet.lib RakNet.dll, tried 
with /s command as well) or something is amiss with the linker. Either 
way, I'm not getting the symbols from RakNet needed in order to use it.

On a final note, error messages I'm getting...
C:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug RakNet.lib *.obj
C:\dmd\bin\..\..\dm\bin\link.exe 
*+chat+raknet\server+raknet\raknet+raknet\client+raknet\packetenumerations+raknet\packetpriority+raknet\networktypes,chat.exe,,RakNet.lib+user32+kernel32,chat.def/co/noi;

OPTLINK (R) for Win32  Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

rakclient.obj(rakclient)  Offset 000D9H Record Type 0091
 Error 1: Previous Definition Different : 
?UNASSIGNED_PLAYER_ID@@3UPlayerID@@B (const PlayerID UNASSIGNED_PLAYER_ID)
rakserver.obj(rakserver)  Offset 000D9H Record Type 0091
 Error 1: Previous Definition Different : 
?UNASSIGNED_PLAYER_ID@@3UPlayerID@@B (const PlayerID UNASSIGNED_PLAYER_ID)
rakbitstream.obj(rakbitstream)
 Error 42: Symbol Undefined ?Read@BitStream@RakNet@@QAE_NPAD_OH@Z
rakbitstream.obj(rakbitstream)
 Error 42: Symbol Undefined ?Read@BitStream@RakNet@@QAE_NAAN@Z
rakbitstream.obj(rakbitstream)
 Error 42: Symbol Undefined ?Read@BitStream@RakNet@@QAE_NAAM@Z
rakbitstream.obj(rakbitstream)
 Error 42: Symbol Undefined ?Read@BitStream@RakNet@@QAE_NAAH@Z
rakbitstream.obj(rakbitstream)
 Error 42: Symbol Undefined ?Read@BitStream@RakNet@@QAE_NAAI@Z
rakbitstream.obj(rakbitstream)
 Error 42: Symbol Undefined ?Read@BitStream@RakNet@@QAE_NAAF@Z
rakbitstream.obj(rakbitstream)
 Error 42: Symbol Undefined ?Read@BitStream@RakNet@@QAE_NAAG@Z
rakbitstream.obj(rakbitstream)
etc. etc.

Kudos to anyone who can figure out what is wrong. I'm starting to give 
up on the windows port. Anyways, thanks to JC, JR, Derek, and anyone 
else who has time enough to read this : )

~ Clay
November 24, 2005
Re: linking C++ to D on windows troubles...
I recommend taking this sample code:

extern (D) int food(char c, int x)
{
   return c / x;
}

extern (C) int fooc(char c, int x)
{
   return c / x;
}

extern (C++) int foocpp(char c, int x)
{
   return c / x;
}

extern (Windows) int foow(char c, int x)
{
   return c / x;
}

and compile it. Run obj2asm on the resulting obj file. Then you'll see the
different name mangling schemes, and the different calling conventions.

The linker doesn't know anything about function calling conventions. Nada,
zip. It only deals with the mangled name, and tries to match the mangled
name identifier strings. If they don't match, it won't link.

Therefore, if things don't link due to "undefined symbols", and it's a
mystery why, then:

1) obj2asm the .obj file that you assume should define the symbol.
2) obj2asm the .obj file that you assume should reference the symbol.

Compare the names. If they don't match, or are missing, you have a good
starting point to figure out where things went wrong.
Top | Discussion index | About this forum | D home