David Schwartz 426 Posted March 16, 2020 for DLL importing, there are lots of {$IFDEF WIN32} stdcall {$ENDIF} constructs I'm seeing. I'm thinking this is for distinguishing between 16-bit and 32-bit library calls. What about 64-bit? Do you need 'stdcall'? Or something else? Or nothing? Share this post Link to post
Remy Lebeau 1394 Posted March 16, 2020 (edited) Unlike in 32bit, multiple calling conventions simply do not exist in 64bit. There is only 1 calling convention, and it is dictated by the 64bit ABI itself. Keywords like 'cdecl' and 'stdcall' are ignored when compiling for 64bit, so as not to break code that is being ported from 32bit. Edited March 16, 2020 by Remy Lebeau 1 Share this post Link to post
David Heffernan 2345 Posted March 16, 2020 The ifdef is pointless and wasteless. On x64 stdcall is, like all calling conventions, ignored. So remove the ifdef and leave stdcall there for the platform that it has meaning. 1 Share this post Link to post
David Schwartz 426 Posted March 16, 2020 I ran Dr. Bob's HeadConv to convert several .h files for a DLL to Delphi, and it sprinkles these IFDEFS into all of the function calls. They're needed for older 16-bit stuff, but I haven't run into any in years. It's mainly that I wasn't sure about 64-bit needs. Glad they're no longer of any use in 64-bit mode. Share this post Link to post
Arnaud Bouchez 407 Posted March 17, 2020 From the code point of view, there is a single calling convention on Delphi for x86_64. But in practice, on Win64, they may be several calling conventions, e.g;. __vectorcall https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_vectorcall This is not yet supported with Delphi - and I doubt it will any day soon, since we have so poor support of vectorization in our compiler. Let's hope a vectorcall; attribute would be implemented someday in Delphi! 🙂 It is supported by FPC - which seems more advanced in terms of optimization and vectorization: https://wiki.freepascal.org/FPC_New_Features_3.2#Support_for_Microsoft.27s_vectorcall_calling_convention Last note: for regular calls, there is a single calling convention per ABI on 64-bit. But the ABI itself (i.e. how parameters are passed and stack handled) is not the same on Windows and POSIX. The Windows 64-bit ABI differs from the Linux/POSIX/SystemV 64-bit ABI on x86_64. Check https://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventions It won't affect regular pascal code. But if you mess with assembly, ensure you use the right registers and stack alignment! Share this post Link to post
David Schwartz 426 Posted March 17, 2020 Thanks, but in this case, I'm only dealing with Windows and two versions of the same DLL -- a 32-bit and a 64-bit version. Share this post Link to post
A.M. Hoornweg 144 Posted March 18, 2020 The default calling convention in Delphi is "register" (the compiler tries to pass parameters in registers if possible to speed things up). The "Stdcall" convention is used throughout by the 32-bit Windows API (which consists of DLL's). So, for consistency's sake, it makes sense to adopt that calling convention for your own 32-bit DLL's as well. "Stdcall" tells the compiler that the caller of the function will pass all parameters on the stack in a right-to-left sequence and that the function itself is responsible for cleaning up the stack before returning. As Remy Lebeau pointed out, in 64-bit Windows there's only one calling convention. So you could do something like this: //in the DLL: Procedure MyProc; {$ifdef win32} Stdcall;{$endif} Export; begin .. end; ... exports 'MyProc'; //In the exe: Procedure MyProc; {$ifdef win32} Stdcall;{$endif} external 'mydll.dll'; Share this post Link to post
David Heffernan 2345 Posted March 18, 2020 31 minutes ago, A.M. Hoornweg said: The default calling convention in Delphi is "register" (the compiler tries to pass parameters in registers if possible to speed things up). The "Stdcall" convention is used throughout by the 32-bit Windows API (which consists of DLL's). So, for consistency's sake, it makes sense to adopt that calling convention for your own 32-bit DLL's as well. "Stdcall" tells the compiler that the caller of the function will pass all parameters on the stack in a right-to-left sequence and that the function itself is responsible for cleaning up the stack before returning. As Remy Lebeau pointed out, in 64-bit Windows there's only one calling convention. So you could do something like this: //in the DLL: Procedure MyProc; {$ifdef win32} Stdcall;{$endif} Export; begin .. end; ... exports 'MyProc'; //In the exe: Procedure MyProc; {$ifdef win32} Stdcall;{$endif} external 'mydll.dll'; As discussed above the conditional code simply adds clutter for no benefit. The compiler has already handled the issue for you. Remove the conditional, and let the compiler ignore stdcall in x64. A second point is the use of the export directive. It is also always ignored (a hangover from 16 bit days). Again it should be removed. Therefore the best practise would be to write: procedure MyProc; stdcall; And that's it. Obviously you still need the exports list somewhere. 2 Share this post Link to post