FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

HowTo: link to c code?
Goto page 1, 2  Next
 
Post new topic   Reply to topic     Forum Index -> General
View previous topic :: View next topic  
Author Message
Lynn



Joined: 27 Aug 2004
Posts: 89

PostPosted: Fri Oct 08, 2004 8:51 am    Post subject: HowTo: link to c code? Reply with quote

<alert comment="newbie">

I'm puzzled on the appropriate way to link a D program to a library made up of C code (such as mysql, sqlite, wxwindows, zlib, 7-zip, etc.) The documentation has several references that this is possible, but I haven't come across an actual example.

In the trivial sample code below, I can get it to work if I compile the C code with the DMC compiler and use the Digital Mars librarian.

But in the general (and probably more typical) case for real world software packages, that doesn't seem like it would be a practical approach. I wouldn't think that makefiles for DMC would typically be available, even if the source code was available.

I think I understand about making a D wrapper module for the function definitions, but eventually doesn't the D main program have to link with something that the DigitalMars linker/librarian can comprehend? I mostly use Visual C++ 6.0, and its .lib output doesn't seem acceptable to dmd or lib.

Code:
//LibC.h
#ifndef _LIBC_H
#define _LIBC_H

__declspec( dllexport ) int AddTwoInts(int first, int second);
__declspec( dllexport ) int SubTwoInts(int first, int second);

#endif


Code:
//libc.c
__declspec( dllexport ) int AddTwoInts(int first, int second) {
  int sum = first + second;
  return sum;
}

__declspec( dllexport ) int SubTwoInts(int first, int second) {
  return first - second;
}


Code:
//TestLibC.cpp
extern "C" {
#include "LibC.h"
}

void main()
{
  int rc = AddTwoInts(123, 456);
  printf("RC: ?d\n", rc);
  rc = SubTwoInts(579, 123);
  printf("RC: ?d\n", rc);
}


Code:
//TestLibC.d
import std.stdio;

extern (C) int AddTwoInts(int first, int second);
extern (C) int SubTwoInts(int first, int second);

void main ()
{
  int rc = AddTwoInts(123, 456);
  writefln("RC: ", rc);
}


</alert>
Back to top
View user's profile Send private message
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Fri Oct 08, 2004 11:57 am    Post subject: Reply with quote

Hello Lynn,

From my experience, it is pure frustration using foreign libs with both dmc and dmd. This has been discussed many times, and you'll hear of tools such as coff2omf and implib often. The problem usually arises when you mush use a 3rd party library for which you've only been provided with the library archive and the headers. As you mention, often the library itself is compiled with some system other then dmc (ie. MS Visual C/C++). Well, the old remedy was to use coff2omf to convert the library to the format dmc could understand. But then MS came out with an updated coff format, so then you FIRST were supposed to track down a MS linker utility that supports the /convert option, use it on the lib file, then call coff2omf, then use it with dmc. Complicated? Yep. In fact that linker tool seems to be very hard to find. These days, it appears to be nigh to impossible to convert the old omf format reliably.... at least I've had little success with the utility myself.

So that leaves you with two choices that I can think of:

(1) Hope the library project you need to use is open source so that you can recompile it into a library with dmc. Then you can be assured that dmd will link with it appropriately. This is problematic if the source has not been stream-lined for dmc. You have more work cut out for you because you must prep the source/makefiles yourself.

(2) Hope the library, if not open source, is at least distributed as a dll. If this is so, you have a chance to create a compatible import lib that you can use to link with your dmd project. This in itself is a major pain also, but perhaps less so then option #1. In this instance, though, dmc still makes things tricky to work with sometimes. For example, the implib you create from the dll is immediately useless until you use a whole wack of tools to set up a proper module definition file (*.def) for the library. This is usually necessary for dll files that will have a __stdcall calling convention peculiar to windows because dmc has the habit of appending @## to all function symbols in the library (where ## is the bytes defining the functions parameter list; so the game here is to figure the ## for each function in the header file and insert that into the *.def file). If the __stdcall is not used in the dll, (a fact usually discoverable by the headers definition of WINAPI for each function declaration), then this probably isn't an issue and the implib will be immediatly useful. This would save a ton of work. In the case of those libraries that require the @## values, Jan Knepper provides a modified implib that supposed to do all the work of determing the *.def @## values for you. If it worked, this would make option #2 the preferred method in all cases. But I've failed to get it to work even once and very little instruction is availabe for it use.

As it stands, I've had to resort to using tools from Borland's toolset (implib, impdef) mixed with dmc's (implib, lib). I've also had to hand modify the *.def files to get things finally working appropriately with dmc. I may sometimes also resort to open watcom and gcc tools when necessary.

Really this is probably the most significant weakness of the digitalmars compiler system. They interface very poorly with outside formats. If you are developing utterly and completely with the dmc and dmd toolset, you're fine. But any mixing is a major headache.

Well, I've droned on long enough.... Perhaps someone can give you a little more helpful details. Smile

Later,

John

PS. Much of my interest in this topic got resparked when, just recently, I worked many hours to get dmc to link with opengl32.lib and glu32.lib. Both libraries provided with the cd version digitalmars dmc were incomplete (ie. missing functions). I had to go through a fairly lengthy process to grab the win XP system versions of the dll and convert them to a linkable solution for dmc. I did it, but it was a painful experience. Nonetheless, it was rewarding to finally get it working.
Back to top
View user's profile Send private message
Lynn



Joined: 27 Aug 2004
Posts: 89

PostPosted: Fri Oct 08, 2004 2:07 pm    Post subject: Reply with quote

Hi John,

Thanks for the very informative "drone". I looked in the archives for how to link with foreign libs, but apparently didn't search well enough. Sigh.

I've noticed posts about re-writing a tool/utility in D (SqLite, wxWindows, zlib, mysql, 7-zip, etc.) and that seems like a marginal idea. It's hard to see how it would keep up with updates to the base tool/utility that was written in C. Q/A would be a problem, as well as performance.

For example, I was trying to use the D version of zlib and found a show-stopper bug that indicated to me that I was one of the first persons to ever use zlib.d ... decompress didn't work for anything beyond a trivial test case. That was zlib.d based on 1.1.4 ... so somebody tackled zlib 1.2.1 (Walter?). It seems to work correctly now, but also seems much slower that the C version. That seems like a pretty good example of the situation that we face.

Perhaps the most helpful effort would be dmc makefiles that were kept up to date for the actual C code ... which sounds like a tedious, thankless task with low prospects of qualified volunteers to wrestle with knarly makefiles.
Back to top
View user's profile Send private message
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Fri Oct 08, 2004 6:34 pm    Post subject: Reply with quote

Lynn wrote:
Hi John,

Thanks for the very informative "drone". I looked in the archives for how to link with foreign libs, but apparently didn't search well enough. Sigh.


I'm sorry. I should have mentioned where to look. Did you look through the digitalmars.c++ newsgroup posts? There's a fair bit of discussion about messing with libraries there. I don't know if it's all completely pertinent, but it's a start.

Lynn wrote:
I've noticed posts about re-writing a tool/utility in D (SqLite, wxWindows, zlib, mysql, 7-zip, etc.) and that seems like a marginal idea. It's hard to see how it would keep up with updates to the base tool/utility that was written in C. Q/A would be a problem, as well as performance.


Rewriting the tool/utility in D is periodically the solution, but what a huge effort that is. It's most useful for learning the D language, and, like you said, makes the code susceptable to new bugs and project syncronization issues. That said, if it's done right, the results are wonderful (thinking of several projects on this site right now), but perhaps not always practical.

Lynn wrote:
For example, I was trying to use the D version of zlib and found a show-stopper bug that indicated to me that I was one of the first persons to ever use zlib.d ... decompress didn't work for anything beyond a trivial test case. That was zlib.d based on 1.1.4 ... so somebody tackled zlib 1.2.1 (Walter?). It seems to work correctly now, but also seems much slower that the C version. That seems like a pretty good example of the situation that we face.


Yes, I heard there were several issues with zlib. I think I remember a discussion going on about it the D.bugs newsgroup a little while ago. I can't see why this library couldn't be compiled with dmc. Doing that might be a temporary solution to the D performance issues, until a bugless version of the library appears for D or the dmd compiler optimization is improved upon. Indeed, it might involve tweaking some makefiles as well as the source. I think I've successfully recompiled zlib before with dmc. It wasn't all that hard to make the necessary modifications, if I recall correctly. In fact, I'll take a peek now and see how dmc works with it (for interests sake).

Lynn wrote:

Perhaps the most helpful effort would be dmc makefiles that were kept up to date for the actual C code ... which sounds like a tedious, thankless task with low prospects of qualified volunteers to wrestle with knarly makefiles.


Yes, for lack of better options, this is quite possible. The work is sometimes tedious, yet for the most part, I admit, dmc has succeeded quite admirably with compiling projects that didn't immediatlely support the dmc system (eg. zlib and glfw in my experience). I haven't played with zlib for awhile, but I think I'll try again.

Once you've got a dmc compiled library, accessing it from within a dmd project is actually quite simple (using "extern (C)" and "extern (Windows)" statements; you then simply link the C lib with the dmd project during the link stage. I should mention that using C libraries on linux with dmd is extremely easy in comparison to windows. Since the object formats are pretty much consistant on that platform, there are no obvious issues with accessing the majority of the linux C libraries.

Later,

John
Back to top
View user's profile Send private message
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Fri Oct 08, 2004 7:07 pm    Post subject: Reply with quote

FYI, I was able to compile a static library for the 1.2.1 release of the zlib source using dmc. The example included with the library compiled and linked successfully also. A dll version would require a bit more work (and more familiarity with dmc). I didn't make a dmc Makefile for the project, but doing so for zlib would be fairly simple. dmd should have no trouble linking with such a library.

Later,

John Reimer
Back to top
View user's profile Send private message
Lynn



Joined: 27 Aug 2004
Posts: 89

PostPosted: Fri Oct 08, 2004 9:13 pm    Post subject: Reply with quote

I'd appreciate getting a copy of a dmc prepared zlib.lib. I was considering tackling that task as it seemed doable, but would be glad to benefit from your expertise. I almost think there was a makefile.sc for the semantec compiler/maker that is more or less compatible with dmc (they share a common history?)

Zlib seems stable/mature enough so that a port isn't completely out of the question, but that doesn't seem like a particularly good use of time to convert the code of something that works well. Except as a learning exercise as you note.

The only calls I'm interested in for the D app I'm contemplating are gzopen, gzclose, gzread, compress, and uncompress, so the number of extern (C) statements isn't too bad. Plus there are the structs for gzfile and perhaps some #defines.

The D version of gzread seemed quite a bit slower than the C version.

I was taking a look at wzWindows.lib, but my emerging impression is that it is C++ and thus unusable by D unless converted. Sigh.
Back to top
View user's profile Send private message
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Sat Oct 09, 2004 1:22 am    Post subject: Reply with quote

Lynn wrote:
I'd appreciate getting a copy of a dmc prepared zlib.lib. I was considering tackling that task as it seemed doable, but would be glad to benefit from your expertise. I almost think there was a makefile.sc for the semantec compiler/maker that is more or less compatible with dmc (they share a common history?)


Sure, no problem at all. I'll send the zlib.lib to your email address. It's compiled with no special flags nor optimizations right now. I may play with such things a little more later. I'll also get a simple zlib makefile done up for dmc eventually. Then you can play with different compile options yourself if you want ( I've found no makefile.sc, that I know of).

Yes, Symantec C/C++ is the ancestor of the Digital Mars compiler system. Walter developed the Symantec compiler until it was finally discontinued by Symantec. The rights to the software were returned to Walter. Walter continues to develop this compiler software under the Digitalmars name. It's actually a tremendous toolset if you can stand the poor inter-operability with modern Windows object formats.

Lynn wrote:
Zlib seems stable/mature enough so that a port isn't completely out of the question, but that doesn't seem like a particularly good use of time to convert the code of something that works well. Except as a learning exercise as you note.


True.

Lynn wrote:
The only calls I'm interested in for the D app I'm contemplating are gzopen, gzclose, gzread, compress, and uncompress, so the number of extern (C) statements isn't too bad. Plus there are the structs for gzfile and perhaps some #defines.


Right. Using the functions in your d project should be no problem at all. But perhaps in order to map the structs accurately in D, you might need to know how these struct data items are aligned in the dmc compiled lib? I'm not sure about this. The rest can be easily gleaned from the zlib header file.

Lynn wrote:

The D version of gzread seemed quite a bit slower than the C version.


I haven't tested this myself.

Lynn wrote:

I was taking a look at wzWindows.lib, but my emerging impression is that it is C++ and thus unusable by D unless converted. Sigh.


You mean wxWindows (now known as wxWidgets)? It's a no go there, until someone does one of two things: (1) learns how to fix the swig project to convert the C++ code to D; or (2) goes to all the work of encapsulating the C++ code in C functions such that D can reference them with an extern(C). Either way, it's a huge amount of work. The fact that Python has succeeded in interfacing with wxWidgets indicates that D should be able to do the same. But a simple way is just not immediatly apparent. I agree, though; it would be great to have wxWidgets on D's side.

Later,

John
Back to top
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Sat Oct 09, 2004 11:08 am    Post subject: Reply with quote

[quote="Lynn"]I'd appreciate getting a copy of a dmc prepared zlib.lib. I was considering tackling that task as it seemed doable, but would be glad to benefit from your expertise.[quote]
One ships with the D compiler. It's in /src/phobos/etc/c/zlib.
Back to top
View user's profile Send private message
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Sat Oct 09, 2004 1:10 pm    Post subject: Reply with quote

sean wrote:
Lynn wrote:
I'd appreciate getting a copy of a dmc prepared zlib.lib. I was considering tackling that task as it seemed doable, but would be glad to benefit from your expertise.

One ships with the D compiler. It's in /src/phobos/etc/c/zlib.


Ha... so the C lib and source actually is included there. Shows how much I know.

Well, the point of this at least was that we were talking about the most recent version of zlib, 1.2.1 verses 1.1.4. 1.1.4 is the one included in the d distribution.

As a note, it appears a compiled zlib is also included in the Digitalmars C/C++ distrubition. So really, there's nothing new about it's existance with digitalmars compiler tools. I should have known. Embarassed

At least, there's still no makefile for the most recent version.

Lynn, did you try the zlib.lib included with the D compiler?
Back to top
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Mon Oct 11, 2004 11:32 am    Post subject: Reply with quote

JJR wrote:
Well, the point of this at least was that we were talking about the most recent version of zlib, 1.2.1 verses 1.1.4. 1.1.4 is the one included in the d distribution.

No it's not. Check the latest DMD release notes Smile
Back to top
View user's profile Send private message
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Mon Oct 11, 2004 5:23 pm    Post subject: Reply with quote

sean wrote:
JJR wrote:
Well, the point of this at least was that we were talking about the most recent version of zlib, 1.2.1 verses 1.1.4. 1.1.4 is the one included in the d distribution.

No it's not. Check the latest DMD release notes Smile


You mean the one that says:

Quote:
Upgraded etc.c.zlib to 1.2.1 (thanks to Sean Kelly).


Hmm... you are so right! I wonder how you knew. Smile

Without checking the other files, I had looked in that directory and picked the one file that still said 1.1.4 in it: zlib.html. If I had looked a little further, I would have noticed all the others indicated 1.2.1.

Once again, I earn the foot-in-the-mouth award and a lot of wasted typing. Embarassed

Cheers,

John
Back to top
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Tue Oct 12, 2004 1:00 pm    Post subject: Reply with quote

Oops! I must have missed that one in my updating.
Back to top
View user's profile Send private message
Workaphobia



Joined: 24 Jun 2004
Posts: 17

PostPosted: Wed Oct 13, 2004 3:16 pm    Post subject: Reply with quote

I went through an extraordinary amount of trouble trying to get opengl to work with DMC (not even D) a few months ago. Eventually I was able to use a .def file to generate an import library. I don't even fully understand the library formats and their relation to .dlls and .defs, I just followed a sample. In fact, I believe it was you, JRR, who helped me with that major headache. Smile

I wouldn't recommend asking for help about this sort of thing on the newsgroup. The only response I got, after posting a lengthy explanation of the problem and all the different trains of thought I pursued, was a shameless plug for the DMC CD by Walter himself. But then again, that was the DMC group, which has one hundredth of the activity of the D group.
_________________
"Nifty News Fifty: When news breaks, we give you the pieces."
Back to top
View user's profile Send private message
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Thu Oct 14, 2004 11:55 pm    Post subject: Reply with quote

Workaphobia wrote:
I went through an extraordinary amount of trouble trying to get opengl to work with DMC (not even D) a few months ago. Eventually I was able to use a .def file to generate an import library. I don't even fully understand the library formats and their relation to .dlls and .defs, I just followed a sample. In fact, I believe it was you, JRR, who helped me with that major headache. Smile


I would love to take credit for helping you... but... I just can't Smile although I did ramble on about some of the mechanics, I think. Justin (Jcc7) actually was the one that helped you get that *.def file going. At that time, I didn't think a "def" file was necessary: I thought the implib tool was all that you needed to do the trick. I've changed my mind since after slogging through several hours of frustration on this issue (yet again) while trying to get the glfw library compiled for dmc. I eventually had to implement my own hand modified opengl32.def and glu32.def. Incidentally, Justin's "def" in that topic does not appear to be complete. The undig project also contains opengl32.def and glu32.def files, but I noticed that those are not complete either... a couple of opengl functions were missing that the glfw project needed (glOrtho() I think was one of them)

Workaphobia wrote:
I wouldn't recommend asking for help about this sort of thing on the newsgroup. The only response I got, after posting a lengthy explanation of the problem and all the different trains of thought I pursued, was a shameless plug for the DMC CD by Walter himself. But then again, that was the DMC group, which has one hundredth of the activity of the D group.


You are right; you don't always get too much help over there. I've had to dig through the newsgroup and documentation myself to get the answers I needed. It wasn't very easy. When I asked a similar question on the dmc group over a year ago, I wasn't really helped either. I was just referred to Jan's implib which didn't work at all.

The D group might be a different matter. It certainly can't hurt to ask questions there or here.
Back to top
View user's profile Send private message
jcc7



Joined: 22 Feb 2004
Posts: 657
Location: Muskogee, OK, USA

PostPosted: Fri Oct 15, 2004 8:54 am    Post subject: Reply with quote

JJR wrote:
Justin (Jcc7) actually was the one that helped you get that *.def file going. At that time, I didn't think a "def" file was necessary: I thought the implib tool was all that you needed to do the trick.
Seems like there should be an easier way, but .def files usually work for me and my others attempts tend to fail. So I return to .def's even though they seem messy and unnecessary.

JJR wrote:
Incidentally, Justin's "def" in that topic does not appear to be complete. The undig project also contains opengl32.def and glu32.def files, but I noticed that those are not complete either... a couple of opengl functions were missing that the glfw project needed (glOrtho() I think was one of them)
Right. I don't even remember where .def that I pasted into the topic originated. I was trying to explain how to use the linker error message to solve the problem with a .def file. I've used various tricks to write .def files, but they're all kind of hacky. I don't know the best way to find all of the definitions, so if the linker complains about another one, I just add it when I find it.

Maybe we should put the best .def files in the SVN for the Bindings project or something like that.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> General All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group