Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2010-03

Linking statically C code with stdcall functions

14 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

cobines

Hello,

I'm trying to link my program statically with bzip2 library under Win32. The exported functions are declared as stdcall. I can link dynamically by declaring functions like this:

function BZ2_bzCompressInit(...): Integer; stdcall; external 'bz2';

It seems that whenever I explicitly give the library name after 'external' FPC always links dynamically, so if I want to link statically I do:

{$LINKLIB bz2}
function BZ2_bzCompressInit(...): Integer; stdcall; external;

But the names are mangled FPC style:

# nm abbzip2.o | grep -i bzCompressInit
U ABBZIP2_BZ2_BZCOMPRESSINIT$TBZSTREAMREC$LONGINT$LONGINT$LONGINT$$LONGINT

I found I can do this by specifying names of the functions, but I have to use mangled names:

{$LINKLIB bz2}
function BZ2_bzCompressInit(...): Integer; stdcall; external name
'';

Is there a way I can declare the external function to use "C" style mangling?

cobines

Reply by email

Jonas Maebe
to cobines
cobines wrote
Is there a way I can declare the external function to use "C" style mangling?

That's currently only possible if the function also uses the C calling convention.

Jonas

Reply by email

cobines
to Jonas Maebe: That's currently only possible if the function also uses the C calling convention. Jonas

2010/3/5 Jonas Maebe :

Show quoted text 8 lines
On 05 Mar 2010, at 06:36, cobines wrote: > Is there a way I can declare the external function to use "C" style > mangling? That's currently only possible if the function also uses the C calling convention.

Ah, I see. Thanks.

2010/3/5 Marco van de Voort :

Show quoted text 10 lines
In our previous episode, cobines said: > > {$LINKLIB bz2} > function BZ2_bzCompressInit(...): Integer; stdcall; external name > ''; > > Is there a way I can declare the external function to use "C" style mangling? That's (VB like) decoration, not C mangling. Only VS compilers use it. Afaik Delphi supports it neither.

You're right, apparently it has nothing to do with C.

I am using MinGW GCC and it also adds this decoration.

Someone did this with Borland C++ 5 and Delphi (don't know which version), but Borland does not use this decoration and Delphi imports the functions by using plain undecorated names. I'll see, maybe there's a way to disable it in GCC.

cobines

Reply by email

Henry Vermaak
to cobines
cobines wrote
You're right, apparently it has nothing to do with C.

According to this, it has:

http://en.wikipedia.org/wiki/Name_mangling#C_name_decoration_in_Microsoft_Windows

Show quoted text 7 lines
I am using MinGW GCC and it also adds this decoration. Someone did this with Borland C++ 5 and Delphi (don't know which version), but Borland does not use this decoration and Delphi imports the functions by using plain undecorated names. I'll see, maybe there's a way to disable it in GCC.

You can pass --kill-at as an option to ld when you link the library (or gcc -Wl,--kill-at).

Henry

Reply by email

Marco van de Voort
to Henry Vermaak

In our previous episode, Henry Vermaak said:

Show quoted text 5 lines
> You're right, apparently it has nothing to do with C. According to this, it has: http://en.wikipedia.org/wiki/Name_mangling#C_name_decoration_in_Microsoft_Windows

But the system libraries using stdcall do not use it, so apparantly it is turned off there. It makes more sense to make stdcall adhere to the system calling convention than the MSVC mangled version one. (that'd be a new modifier)

Reply by email

Henry Vermaak
to Marco van de Voort: In our previous episode, Henry Vermaak said: But the system libraries using stdcall do…
Marco van de Voort wrote 11 lines
In our previous episode, Henry Vermaak said: > > You're right, apparently it has nothing to do with C. > > According to this, it has: > > http://en.wikipedia.org/wiki/Name_mangling#C_name_decoration_in_Microsoft_Windows But the system libraries using stdcall do not use it, so apparantly it is turned off there. It makes more sense to make stdcall adhere to the system calling convention than the MSVC mangled version one. (that'd be a new modifier)

It's a bit useless if you can't link to any other libraries, no? I guess you can still use ld instead of the internal llinker (and even import libs).

Henry

Reply by email

cobines
to Henry Vermaak: You can even use --enable-stdcall-fixup when you you link your pascal program with ld. …

2010/3/5 Henry Vermaak :

Show quoted text 10 lines
On 5 March 2010 12:22, Henry Vermaak wrote: > > You can pass --kill-at as an option to ld when you link the library > (or gcc -Wl,--kill-at). You can even use --enable-stdcall-fixup when you you link your pascal program with ld.  That should try and do what the docs call "fuzzy linking". See: http://sourceware.org/binutils/docs/ld/Options.html#Options

I know and I use --kill-at when I build the dll, but I don't actually link the library if I want static linking. I put the library's object files into an archive (ar r libbz2.a *.o) and I link the pascal program with this archive (add {$LINKLIB bz2}). Or is it wrong method of linking statically?

In the object files the names are decorated ()
and that's how I have to specify them. I wanted to avoid specifying this decoration because on Win64 it is not applied (I don't know if only by GCC or other compilers too) and thought maybe FPC would do this for me. But I guess I can use {$IFDEF}'s and just put different names on Win32 and Win64.

cobines

Reply by email

Marco van de Voort
to Henry Vermaak: It's a bit useless if you can't link to any other libraries, no? I guess you can still…

In our previous episode, Henry Vermaak said:

Show quoted text 6 lines
> But the system libraries using stdcall do not use it, so apparantly it is > turned off there. It makes more sense to make stdcall adhere to the system > calling convention than the MSVC mangled version one. (that'd be a new > modifier) It's a bit useless if you can't link to any other libraries, no?

You can, you just have to specify the decoration. Or if there is a large scale need a modifier or directive to modify stdcall to include decoration could be made by interested parties.

I guess you can still use ld instead of the internal llinker (and even import libs).

I'd just add the decoration manually. It is typically a one-off effort.

Reply by email

Henry Vermaak
to Marco van de Voort
Marco van de Voort wrote 7 lines
In our previous episode, Henry Vermaak said: > > It's a bit useless if you can't link to any other libraries, no? You can, you just have to specify the decoration. Or if there is a large scale need a modifier or directive to modify stdcall to include decoration could be made by interested parties.

Maybe a command line param that does a more fuzzy linking?

> I guess you can still use ld instead of the internal llinker (and even > import libs). I'd just add the decoration manually. It is typically a one-off effort.

Except if you have cross platform code, then you need an ifdef for every function you import :(

Henry

Reply by email

Marco van de Voort
to Henry Vermaak

In our previous episode, Henry Vermaak said:

Show quoted text 9 lines
Maybe a command line param that does a more fuzzy linking? >> I guess you can still use ld instead of the internal llinker (and even >> import libs). > > I'd just add the decoration manually. It is typically a one-off effort. Except if you have cross platform code, then you need an ifdef for every function you import :(

It's still a one off. Annoying for hundreds of calls, but not really a problem for a few tens. It will be more work to craete a patch to fix this :-)

Reply by email

Henry Vermaak
to Marco van de Voort
Marco van de Voort wrote 14 lines
In our previous episode, Henry Vermaak said: > Maybe a command line param that does a more fuzzy linking? > > >> I guess you can still use ld instead of the internal llinker (and even > >> import libs). > > > > I'd just add the decoration manually. It is typically a one-off effort. > > Except if you have cross platform code, then you need an ifdef for > every function you import :( It's still a one off. Annoying for hundreds of calls, but not really a problem for a few tens. It will be more work to craete a patch to fix this :-)

Is this a big task? I've never looked at the code for the linker.

Reply by email

Marco van de Voort
to Henry Vermaak

In our previous episode, Henry Vermaak said:

Show quoted text 10 lines
>> > I'd just add the decoration manually. It is typically a one-off effort. >> >> Except if you have cross platform code, then you need an ifdef for >> every function you import :( > > It's still a one off. Annoying for hundreds of calls, but not really a > problem for a few tens. It will be more work to craete a patch to fix this > :-) Is this a big task? I've never looked at the code for the linker.

I'm no inner-compiler developer, but it probably depends on what you want to do. Just fuzzy linking trying to match undecorated functions with decorated ones, or really evaluate the number of arguments to create the decoration on the "header" side, and then do exact linking.

The fuzzy option is easier, but the other stuff is probably also needed for generating libs with compatible decoration, as well as making use of the main use of decoration: overloading external symbols on the basis of number of parameters. (default param alike probably)

Reply by email