Subject: Re: Linking with Borland C
From: [email-masked] (Anders Norlander)

18 Sep 1998 00:09:22 -0700
Message-ID: <[email-masked]>
References: <Pine.GSO.4.02.9809141742260.27342-100000@brutus>
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
To: "Félix Valado Pomarinho" <[email-masked]>
Cc: [email-masked]

Félix Valado Pomarinho wrote:
> 
>         Hello,
> 
>         I'm more or less aware of the troubles linking gcc DLL's using
> VC++. I am trying to use a gcc DLL created with the dllhelper utility
> in a program that's compiled using Borland C and I'm having a lot of
> problems.
> 
>         1) Is there any known solution to this problem?

I have successfully created a DLL and linked it with an
app compiled by BC, but it is cumbersome business. The
problem, as I see it, is that you cannot use the same .DEF
files with BC and dlltool since the exported names are
decorated differently by the different tools.
GCC names stdcall functions <name>@<n>, BC names them
just <name>. C functions are prefixed by a single '_'
in both GCC and BC. Note that I have only done this
with BC++ 5.01 and not C++ builder.

To import the stdcall function `foo' from FOO.DLL and
call it from a BC compiled function, use the following
..DEF file:
-- BEGIN FOO.DEF --
LIBRARY FOO.DLL
EXPORT
	foo
-- END FOO.DEF --
Execute the command `implib foo.lib FOO.DEF' to create the
import library. The trouble is that `foo' is decorated
`foo@0' (zero arguments) by GCC. Therefore you will have
to export it as `foo', even though it is named `foo@0'.
This can be done with the following export statement in
you .DEF file: `foo=foo@0'.
That's for stdcall functions.

Importing C functions can be accomplished in two ways.
Suppose you want to import a C function with the
prototype `int foo(void);'. The function will be prefixed
by '_' by both GCC and BC, but when exporting the function
you use `foo' as the export statement in the DEF file and
BC looks for `_foo'. Here comes the trick...
use `_foo=foo' as the export statement in your DEF file
when creating the DLL and `_dll_cdecl' when creating the
import library for BC... or you can use `foo' when creating
the DLL and `_foo=foo' when creating the import library
for BC.

Here's a complete example:
-- BEGIN SAMPLE ---
foo.c:
int
foo(void)
{
	return 0;
}

int
STDCALL
bar(void)
{
	return 1;
}

fooexp.def:
EXPORTS
	foo
	bar=bar@0

fooimp.def:
LIBRARY foo.dll	//This is important if the file does not have
		//the same basename as the DLL (i.e foo.dll).
		//If the file was named foo.def it would not be necessary
		//Remove these comments before using implib!
EXPORTS
	_foo=foo
	bar

callfoo.c:
#include <stdio.h>

extern int foo(void);
extern int _stdcall bar(void); /* _stdcall is a keyword in BC */

int
main()
{
	printf("foo(): %d\nbar(): %d\n", foo(), bar());
	return 0;
}

int
main()
{
	printf("foo(): %d\nbar(): %d\n", foo(), bar());
	return 0;
}

-- END SAMPLE --
Now execute the following commands:
gcc -c foo.c  					// Compile foo and bar
dllwrap -o foo.dll --def fooexp.def foo.o	//Create the DLL
implib foo.lib fooimp.def			//Use borland tool implib to create
						//import library `foo.lib'
bcc32 callfoo.c foo.lib				//Create app

Now you have a working DLL and import library!
(Depending on how you want exported functions to be named
you may change the DEF files as described above).
The convention seems to be not to export decorated
function names. The whole would be a lot easier if the
same DEF file could be used for both set of tools.
Hope this helps!

/Anders
-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".