www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DMC to Create C .lib ?

reply Chris Andrews <CodexArcanum gmail.com> writes:
I'm working on a wrapper to a C dll and I think that I'll need to create a .lib
file eventually to connect my D code to the C library.  

I've experimented with this a little, including using ipmlib to create the lib,
which creates a lib but not one that works right (I think it mangles the names
wrong.)  However, the excellent linkdef tool works to create a good .def which
allows implib to create a proper lib.

Still, that seems a fussy way to build this: write it wrong, break it, use
linkdef and implib to fix it.  I have the source code for that dll, so what I'm
wondering is, can I just use some other DM tools (DMC?) to compile that C code
and get a proper .lib from that?
Mar 19 2009
next sibling parent Sergey Gromov <snake.scaly gmail.com> writes:
Thu, 19 Mar 2009 17:27:30 -0400, Chris Andrews wrote:

 I'm working on a wrapper to a C dll and I think that I'll need to create a
.lib file eventually to connect my D code to the C library.  
 
 I've experimented with this a little, including using ipmlib to create the
lib, which creates a lib but not one that works right (I think it mangles the
names wrong.)  However, the excellent linkdef tool works to create a good .def
which allows implib to create a proper lib.
 
 Still, that seems a fussy way to build this: write it wrong, break it, use
linkdef and implib to fix it.  I have the source code for that dll, so what I'm
wondering is, can I just use some other DM tools (DMC?) to compile that C code
and get a proper .lib from that?
Use coffimplib on your regular .lib file: http://www.digitalmars.com/ctg/coffimplib.html Get it at ftp.digitalmars.com. I'm advertising coffimplib so much that I probably need a badge already, "Want to create an import library? Ask me how!"
Mar 19 2009
prev sibling next sibling parent Trass3r <mrmocool gmx.de> writes:
Chris Andrews schrieb:
 Still, that seems a fussy way to build this: write it wrong, break it, use
linkdef and implib to fix it.  I have the source code for that dll, so what I'm
wondering is, can I just use some other DM tools (DMC?) to compile that C code
and get a proper .lib from that?
If you have source code, you can of course compile a static library. dmc -c *.c lib -c libname.lib *.obj
Mar 19 2009
prev sibling next sibling parent reply Chris Andrews <CodexArcanum gmail.com> writes:
Sergey Gromov Wrote:

 "Want to create an import library? Ask me how!"
Well since you offered... ;) I tried out coffimplib, but it's not yeilding the results I need. I compared the linkdef generated .def files with coffimplib's and the missing part is pretty clear: linkdef: EXPORTS _TCOD_console_flush 0 = TCOD_console_flush _TCOD_console_init_root 16 = TCOD_console_init_root coffimplib: EXPORTS _TCOD_console_flush = TCOD_console_flush _TCOD_console_init_root = TCOD_console_init_root Those missing numbers (something to do with the size of the parameters, right?) are needed and not being provided by the tool. Thoughts?
Mar 24 2009
parent Sergey Gromov <snake.scaly gmail.com> writes:
Tue, 24 Mar 2009 22:31:52 -0400, Chris Andrews wrote:

 Sergey Gromov Wrote:
 
 "Want to create an import library? Ask me how!"
Well since you offered... ;) I tried out coffimplib, but it's not yeilding the results I need. I compared the linkdef generated .def files with coffimplib's and the missing part is pretty clear: linkdef: EXPORTS _TCOD_console_flush 0 = TCOD_console_flush _TCOD_console_init_root 16 = TCOD_console_init_root coffimplib: EXPORTS _TCOD_console_flush = TCOD_console_flush _TCOD_console_init_root = TCOD_console_init_root Those missing numbers (something to do with the size of the parameters, right?) are needed and not being provided by the tool. Thoughts?
You're talking about Doryen Library project, right? My thought is that TCOD_console_flush is actually cdecl and must be declared as extern(C), while you seem to declare it as extern(Windows) which is stdcall. What you get with linkdef is corrupted stack. This is why coffimplib is absolute best when you have the right COFF import library: it allows to catch this sort of errors.
Mar 25 2009
prev sibling parent reply Chris Andrews <CodexArcanum gmail.com> writes:
Sergey Gromov Wrote:

 You're talking about Doryen Library project, right?
 
 My thought is that TCOD_console_flush is actually cdecl and must be
 declared as extern(C), while you seem to declare it as extern(Windows)
 which is stdcall.  What you get with linkdef is corrupted stack.  This
 is why coffimplib is absolute best when you have the right COFF import
 library: it allows to catch this sort of errors.
Hah, you got me. Yeah, I'm toying with a wrapper for Doryen Library in D. I'm trying to not talk too much about it, since I don't know if I'm skilled enough to write and implement it, nor dedicated enough to finish it. :p We'll see. All the methods were preprended by TCODLIB_API, which is a typedef to __declspec(dllexport) ( or __declspec(import) ) which I thought (according to the guide) translates as export extern(Windows) I guess I'll try externing to C instead, and try to coffimp the library again. Perhaps the "visual studio" library is a bad one to use, and I should try the "Mingw" .a file.
Mar 26 2009
next sibling parent Mike Parker <aldacron gmail.com> writes:
Chris Andrews wrote:
 Sergey Gromov Wrote:
 
 You're talking about Doryen Library project, right?

 My thought is that TCOD_console_flush is actually cdecl and must be
 declared as extern(C), while you seem to declare it as extern(Windows)
 which is stdcall.  What you get with linkdef is corrupted stack.  This
 is why coffimplib is absolute best when you have the right COFF import
 library: it allows to catch this sort of errors.
Hah, you got me. Yeah, I'm toying with a wrapper for Doryen Library in D. I'm trying to not talk too much about it, since I don't know if I'm skilled enough to write and implement it, nor dedicated enough to finish it. :p We'll see. All the methods were preprended by TCODLIB_API, which is a typedef to __declspec(dllexport) ( or __declspec(import) ) which I thought (according to the guide) translates as export extern(Windows) I guess I'll try externing to C instead, and try to coffimp the library again. Perhaps the "visual studio" library is a bad one to use, and I should try the "Mingw" .a file.
The __declspec directive does not affect the calling convention, but whether or not the function is visible outside the DLL. Any function in a DLL that should be visible to the client program must be declared with the __declspec directive, so you'll see that on every Windows DLL function you interface with. You should only use extern(Windows) on the D side when you see a function declared as stdcall (most commonly this is done via a macro such as WINAPI, or STDCALL).
Mar 27 2009
prev sibling parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Fri, 27 Mar 2009 00:18:47 -0400, Chris Andrews wrote:

 Sergey Gromov Wrote:
 
 You're talking about Doryen Library project, right?
 
 My thought is that TCOD_console_flush is actually cdecl and must be
 declared as extern(C), while you seem to declare it as extern(Windows)
 which is stdcall.  What you get with linkdef is corrupted stack.  This
 is why coffimplib is absolute best when you have the right COFF import
 library: it allows to catch this sort of errors.
Hah, you got me. Yeah, I'm toying with a wrapper for Doryen Library in D. I'm trying to not talk too much about it, since I don't know if I'm skilled enough to write and implement it, nor dedicated enough to finish it. :p We'll see.
I just wanted to double-check that you did the conversion correctly. So I ended up finding out what the hell TCOD was. Sorry for the spoiler! :D
 All the methods were preprended by TCODLIB_API, which is a typedef to
 __declspec(dllexport) ( or __declspec(import) ) which I thought
 (according to the guide) translates as export extern(Windows) 
__declspec(dllexport) just directs the compiler to make this function available from outside your DLL. It does not change calling convention. It's equivalent to just "export" in D. By default, C uses "cdecl" calling convention ("extern(C)" in D), and C++ uses "fastcall", I think ("extern(C++)" in D). C++ also uses cdecl if explicitly told so via 'extern "C" { ...' construct, usually somewhere in a header with function prototypes. Since every calling convention uses different mangling rules (symbol naming) you can usually tell them apart: functions with simple names with "_" prepended are cdecl, funky long names are fastcall, simple names with num are stdcall (extern(Windows), extern(System)).
 I guess I'll try externing to C instead, and try to coffimp the
 library again.  Perhaps the "visual studio" library is a bad one to
 use, and I should try the "Mingw" .a file.
Visual Studio library should be perfectly fine. P.S. This post really belongs to D.learn.
Mar 27 2009
parent reply Chris Andrews <CodexArcanum gmail.com> writes:
Sergey Gromov Wrote:

 I just wanted to double-check that you did the conversion correctly.  So
 I ended up finding out what the hell TCOD was.  Sorry for the spoiler!
 :D
Hah, no biggie. Good news though, I removed my extern(Windows) and tried the code against the coffimplib altered library and... SUCESS!! So that works... like its supposed to when you're not a huge noob. :p Thanks for the advice in getting that straightened out.
 P.S.
 This post really belongs to D.learn.
Oops, sorry. I'm still picking up the flow of these boards. Advice and questions goes in Learn, while D is for discussion about the language itself, yes?
Mar 29 2009
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Sun, 29 Mar 2009 04:00:47 -0400, Chris Andrews wrote:

 Sergey Gromov Wrote:
 
 I just wanted to double-check that you did the conversion correctly.  So
 I ended up finding out what the hell TCOD was.  Sorry for the spoiler!
 :D
Hah, no biggie. Good news though, I removed my extern(Windows) and tried the code against the coffimplib altered library and... SUCESS!! So that works... like its supposed to when you're not a huge noob. :p Thanks for the advice in getting that straightened out.
Nice to hear! I hope that you actually not "removed your extern(Windows)" but replaced it with extern(C). Otherwise you risk getting D linkage for those functions which is neither C nor C++.
 This post really belongs to D.learn.
Oops, sorry. I'm still picking up the flow of these boards. Advice and questions goes in Learn, while D is for discussion about the language itself, yes?
Well, your question was about linking D with C++ code. Good interaction with C/C++ code is one of D's main selling points. One therefore could guess that there's not much to discuss but rather to ask what they do wrong. No worries though. There are no angry moderators with big plus-throwers here. ;D
Mar 29 2009
parent Chris Andrews <CodexArcanum gmail.com> writes:
Sergey Gromov Wrote:

 I hope that you actually not "removed your extern(Windows)" but replaced
 it with extern(C).  Otherwise you risk getting D linkage for those
 functions which is neither C nor C++.
This is just going to sound silly now, but I was following along the ".h to D" conversion guide, so I basically took the .h files, wrapped them up in extern(C){} and set about translating the rest by hand (typdefs, types, etc). I just replaced all the exports with export extern(Windows). So, if I'm reading it right, what I did was extern everything to C, except what I had explicitly extern(Windows) instead. :P Sometimes I just don't think. But yeah, should all be extern(C) now, so it's all good.
Mar 29 2009