I have a library with udf routines using the cdecl calling convention, required by Firebird. This seems to work well on win32. However when I test these routines with a fpc win32 app declaring external functions with the cdecl or stdcall calling convention gives me a 'entrypoint not found' error. I assume cdecl is obligatory, but can I implement that?
Mailing lists / fpc-pascal / 2009-05
How to call lib routines with cdecl calling convention with win32 app?
7 messages · 3 people · –
- CCoco Pascal 4
- JJonas Maebe 2
- MMarco van de Voort 1
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
In our previous episode, Coco Pascal said:
I have a library with udf routines using the cdecl calling convention, required by Firebird. This seems to work well on win32.
How exactly?
However when I test these routines with a fpc win32 app declaring external functions with the cdecl or stdcall calling convention gives me a 'entrypoint not found' error. I assume cdecl is obligatory, but can I implement that?
Maybe it is a matter of an underscore prefix. Write the declaration full
(cdecl external libname name '_symbol';and experiment with leaving the underscore there or not.
It might also be the need to declare a libname. Windows and OS X afaik have separate linker namespaces for external libs, so you need to declare the name of the module they are in.
Marco van de Voort wrote 8 lines
?
function Y_Odd(const AValue: Int64): LongInt; cdecl; export;
begin
if Odd(AValue) then
Result := -1
else
Result := 0;
end; {Y_Odd}exports
Y_Odd;This works fine with Firebird. If I declare the stdcall calling convention Firebird can't find its entrypoint.
Show quoted text 16 lines
function Y_Odd(const AValue: Int64): LongInt; cdecl; external LibName
name 'libyfbudf.dll';
gives me an Identifier not found "LibName" error.
function Y_Odd(const AValue: Int64): LongInt; cdecl; external
'_libyfbudf.dll';
gives me a File not found _libyfbudf.dll.Coco Pascal wrote 25 lines
cdecl automatically enables C-compiler-compatible name mangling for exported procedures. stdcall doesn't. So it's normal that Firebird does not find the entrypoint when using stdcall, as it does not support FPC-style name mangling.
There is no way to get C name mangling without the calling convention, so you have to manually declare an alias in that case. E.g.,
function Y_Odd(const AValue: Int64): LongInt; cdecl; alias: '_Y_Odd'; export;
Whether or not you need an extra underscore before the alias name depends on the target platform. Win32 requires one.
Jonas
Jonas Maebe wrote 43 lines
I tried
function Y_Odd(const AValue: Int64): LongInt; cdecl; alias: '_Y_Odd';
export;
and
function Y_Odd(const AValue: Int64): LongInt; cdecl; alias: '__Y_Odd';
export;
but still I get the message entrypoint of 'Y_Odd' could not be found in
'libyfbudf.dll'Coco Pascal wrote 8 lines
Then you may want to use some tool to look at the name of the entry point in the dll for the cdecl case, and compare it to the stdcall case. Since I don't use Windows, I cannot help you with this.
Jonas
Jonas Maebe wrote 17 lines
Thanks for the tip! The name in the dll is _Y_Odd indeed. Is it not the function header in the dll that must extended with alias: '_Y_Odd'. The function declaration in the app should be: function _Y_Odd(const AValue: Int64): LongInt; cdecl; external 'libyfbudf.dll';
