FFI Again (last time, I promise!)
Jarvis, Robert P. (Contingent)
Jarvisb at timken.com
Tue Oct 17 12:47:51 UTC 2000
>From the Visual C++ documentation:
__cdecl
Argument-passing order Right to left
Stack-maintenance responsibility Calling function pops the
arguments from the
stack
Name-decoration convention Underscore character (_)
is prefixed to names
Case-translation convention No case translation
performed
__stdcall
Argument-passing order Right to left.
Argument-passing convention By value, unless a pointer
or reference type is
passed.
Stack-maintenance responsibility Called function pops its own
arguments from the
stack.
Name-decoration convention An underscore (_) is
prefixed
to the name. The
name is
followed by the at
sign (@)
followed by the
number of bytes
(in decimal) in the
argument
list. Therefore, the
function
declared as
int func( int a,
double b ) is
decorated as
follows: _func at 12
Case-translation convention None
There used to be a __pascal calling convention which IIRC was similar to
__stdcall except that arguments were pushed from left to right, there
was no name decoration, and case was always translated to uppercase;
however,
this is no longer supported (at least by Visual C++).
The advantage to __stdcall and __pascal is that the function arguments are
popped from the stack by the called function. On the x86 architecture the
RET instruction can do both the <return-from-function> and <pop-args-from-
stack> at the same time, thus saving one instruction per function call.
If you were to call a function with 5 bytes of arguments on the stack here's
how the function epilog would look under the different calling conventions:
__cdecl __stdcall/__pascal
RET 0 RET 5
. .
. .
. .
<back in the <back in the
calling function> calling function>
SUB SP, 5 ...more
...more instructions...
instructions...
So basically __stdcall saves you that SUB SP, x instruction after every
function call in the program. It's not much, but it's something. Note
that this is tuned to the x86 architecture. I don't know if other chips
support the 'return-and-pop-arguments' variant of RET.
Under Windows 9x and NT, __stdcall is the standard calling convention.
Under Win 3.x __pascal was the standard (IIRC). Looking at the VC++
headers it appears that the Mac uses cdecl by default and, true to its
Unix heritage, Linux uses cdecl.
I hope this helps.
Bob Jarvis
Compuware @ Timken
> -----Original Message-----
> From: Kevin Fisher [mailto:kgf at golden.net]
> Sent: Monday, October 16, 2000 7:37 PM
> To: squeak at cs.uiuc.edu
> Subject: FFI Again (last time, I promise!)
>
>
>
> Sorry to bring this up again, but now that I've gotten FFI
> under UNIX working
> I've got a question about the calling syntax.
>
> When creating a method to call an external function, you use
> something like
> this in the method definition:
>
> <cdecl: long 'system' (char*) module:'libc.so.6'>
>
> So, the questions:
>
> 1) Why does UNIX use <cdecl ...> while Mac and Windows use
> <apicall ...>?
> 2) In the above example, I have to use the module
> 'libc.so.6' specifically,
> or else the function call won't work. However, in the X11
> examples the module
> is always set to 'X11' (not libX11.so). Is there any way I
> can call from
> the standard C library without specifically having to reference the
> version-specific libc.so.6? Using module: 'c' doesn't work...
>
> Thanks for any advice!
>
>
More information about the Squeak-dev
mailing list
|