Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function pointer and calling convention

Tags:

float __stdcall (*pFunc)(float a, float b) = (float (__stdcall *)(float,float))0x411280; 

How to declare a function pointer with calling convention? The above gives me an error.

like image 322
Yulo Avatar asked Jan 28 '11 16:01

Yulo


People also ask

What is a function calling convention?

Calling conventions specify how arguments are passed to a function, how return values are passed back out of a function, how the function is called, and how the function manages the stack and its stack frame. In short, the calling convention specifies how a function call in C or C++ is converted into assembly language.

What are the function of pointers?

A function pointer, also called a subroutine pointer or procedure pointer, is a pointer that points to a function. As opposed to referencing a data value, a function pointer points to executable code within memory.

What is difference between function and pointer?

1) Unlike normal pointers, a function pointer points to code, not data. Typically a function pointer stores the start of executable code. 2) Unlike normal pointers, we do not allocate de-allocate memory using function pointers. 3) A function's name can also be used to get functions' address.

How do you call a function from a pointer?

The call by pointer method of passing arguments to a function copies the address of an argument into the formal parameter. Inside the function, the address is used to access the actual argument used in the call. This means that changes made to the parameter affect the passed argument.

What is a calling convention in programming?

In computer science, a calling convention is an implementation-level (low-level) scheme for how subroutines receive parameters from their caller and how they return a result.

What is a function pointer?

Function pointers are simply pointers to the label of the respective function. There's no table of contents (TOC) requirement for function pointers. Floating-point support for older code

What is the correct Convention for passing parameters to a function?

If parameters are passed via varargs (for example, ellipsis arguments), then the normal register parameter passing convention applies. That convention includes spilling the fifth and later arguments to the stack. It's the callee's responsibility to dump arguments that have their address taken.

What is the default calling convention in x64 code?

Submit Thank you. In this article This section describes the standard processes and conventions that one function (the caller) uses to make calls into another function (the callee) in x64 code. Calling convention defaults The x64 Application Binary Interface (ABI) uses a four-register fast-call calling convention by default.


2 Answers

The trick is placing the __stdcall inside the parentheses like this:

float (__stdcall *pFunc)(float a, float b) = (float (__stdcall *)(float,float))0x411280; 

Of course, you are recommended to use a typedef instead, but the same trick applies:

typedef float (__stdcall *FuncType)(float a, float b); 
like image 76
namey Avatar answered Oct 16 '22 19:10

namey


For a regular function, you can usually do:

__cdecl const int func(); __cdecl const int (func)(); const __cdecl int func(); const int __cdecl func(); const int (__cdecl func)(); __cdecl const __cdecl int (__cdecl func)(); 

It is implementation defined whether or not a compiler will accept all of these forms. Clang does. To me, the 5th version makes the most semantic sense, because it is a property of the function and not the return type alone.

You can do all of this with __attribute__((cdecl)) instead of __cdecl, which can also be used after the function, unlike __cdecl

const int (__cdecl func)() __attribute__((cdecl)); 

Now, to declare a constant pointer pfunc to a function with a specific calling convention:

__cdecl const int (*const pfunc)(); const __cdecl int (*const pfunc)(); const int __cdecl (*const pfunc)(); const int (__cdecl *const pfunc)(); const int (*const __cdecl pfunc)(); const int (*__cdecl const pfunc)(); __cdecl const __cdecl int (__cdecl *const pfunc)(); const int (*const pfunc)() __attribute__((cdecl)); 

Note that const has to be after the asterisk as usual. With double function pointers, the pointers can go anywhere with respect to the calling convention, but you have to put it in the correct place with respect to const.

Again, it is implementation defined as to what form a compiler accepts. Clang accepts all forms and correctly interprets them as the type const int (*const)() __attribute__((cdecl))

like image 37
Lewis Kelsey Avatar answered Oct 16 '22 19:10

Lewis Kelsey