digitalmars.D.learn - linking C++ to D on windows troubles...
- clayasaurus (32/32) Nov 19 2005 What is the correct way to link a C++ library to D under windows? I can
- John C (11/43) Nov 19 2005 Sounds like your DLL functions aren't getting exported. You need to use
- clayasaurus (5/72) Nov 19 2005 I mentioned that using the -Lmylib.lib didn't find the symbols for the
- clayasaurus (3/81) Nov 19 2005 Forgot to mention, I found a static lib that I could use instead of a
- clayasaurus (19/106) Nov 19 2005 C:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug -Lrakglue.lib
- John Reimer (14/36) Nov 20 2005 For some reason, the build command line is being processed incorrectly
- John Reimer (4/8) Nov 20 2005 Of course I meant:
- clayasaurus (54/66) Nov 20 2005 Ahh thanks. I'm used to using the -Llib command because that is how it
- Derek Parnell (17/21) Nov 20 2005 [snip]
- Walter Bright (28/28) Nov 24 2005 I recommend taking this sample code:
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
Nov 19 2005
"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 ~ ClaySounds 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
Nov 19 2005
John C wrote:"clayasaurus" <clayasaurus gmail.com> wrote in message news:dlo8gc$19vi$1 digitaldaemon.com...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.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 ~ ClaySounds 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
Nov 19 2005
clayasaurus wrote:John C wrote: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."clayasaurus" <clayasaurus gmail.com> wrote in message news:dlo8gc$19vi$1 digitaldaemon.com...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.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 ~ ClaySounds 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
Nov 19 2005
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: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."clayasaurus" <clayasaurus gmail.com> wrote in message news:dlo8gc$19vi$1 digitaldaemon.com...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.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 ~ ClaySounds 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
Nov 19 2005
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.lib akNetLibStatic.lib; OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights ReservedWhy is buiild giving this warning:OPTLINK : Warning 9: Unknown Option : NOIRAKGLUE.LIBRAKNETLIBSTATIC.LIBFor 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.libC:\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 .libThe 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
Nov 20 2005
John Reimer wrote:Like so: c:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug rakglue.libOf course I meant: C:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug rakglue.lib RakNetLibStatic.lib
Nov 20 2005
John Reimer wrote:John Reimer wrote: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 : ) ~ ClayLike so: c:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug rakglue.libOf course I meant: C:\CINTER~1>build chat.d -g -Rn -full -cleanup -debug rakglue.lib RakNetLibStatic.lib
Nov 20 2005
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][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 AMI 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?
Nov 20 2005
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.
Nov 24 2005