From what I understand, the caller and the callee both need to have the same calling convention. Otherwise, the stack might be corrupted.
WinMain is declared with __stdcall and calls all the functions I've defined. Does this mean all the functions I define should use the stdcall calling convention?
I've tried not using __stdcall and nothing bad happened. I have also seen well-known GUI libraries supporting Windows don't use stdcall. Why is the stack not corrupting?
WinMain is declared with __stdcall and calls all the functions I've defined. Does this mean all the functions I define should use the stdcall calling convention?
No. Calling conventions are handled on a per-function-call basis, right at the call site. The convention dictates how the caller and callee manage the call stack - how parameters are passed, in what order, who cleans up the stack, etc. As long as the caller and callee agree to use the same calling convention on each individual function call, it is perfectly safe for a stdcall function to call a function that uses a different convention, like cdecl, and vice versa. A function's calling convention applies only when:
the function is being entered by a new caller.
the function is returning back to that caller.
the function is accessing its own parameters.
Outside of that, what a function does internally has nothing to with its own calling convention.
For example, lets say that WinMain(), a stdcall function, wants to call a cdecl function.
It does not matter at all that WinMain() is itself a stdcall function. While code execution is inside of WinMain(), it can do whatever it wants. WinMain()'s stdcall convention is applied only upon entry and exit of WinMain() itself. That is the contract WinMain() has with ITS caller.
What matters is that WinMain() must follow the rules of cdecl when setting up the call stack for a cdecl function that it is about to call into, and cleaning up the call stack when that function returns back to WinMain().
The same goes for any function call of any calling convention.
I've tried not using __stdcall and nothing bad happened. I have also seen well-known GUI libraries supporting Windows don't use stdcall. Why is the stack not corrupting?
Because the call stack is being managed correctly at every function call and return, so there is no unbalanced cleanup to corrupt the stack.
I have a c source file in which one of the method is defined as follows:
void QDECL prettyPrintf(int level) {
////// some code.
}
I would like to know what is QDECL.In this case, is it returning QDECL type? As far as my little knowledge in C, a 'void' does not return anything.So, is it a legal statement?
QDECL is probably a preprocessor macro that resolves to a calling convention hint (e.g. __cdecl or __stdcall); This defines how parameters are pushed onto and cleaned up in the call stack, but it does not change the return type of the function. It is mainly used for interoperability when using libraries that use a different default calling convention than the client's.
I just checked the definition of QDECL. It is
#define QDECL __cdecl
Now your declaration becomes,
void __cdecl prettyPrintf(int level)
which is still a function which returns void.
In fact QDECL can still take ( theoretically ) some other forms without altering the return type of your function. It easily could have been
#define QDECL static
Now, your function prototype is
void static prettyPrintf(int level)
which is still a void returning function
QDECL defines the calling convention. This is a macro defined in one of the header files that will evaluate to something like __cdecl or __stdcall.
This has no bearing on the return type of the function. The function is still a void function.
You state in a comment:
My concern here is that if I port the above code to Java, do I need to take care of this?
No you do not. This is purely an issue for interfacing between different native libraries of code. Once the code is in Java you can simply ignore calling convention.
How exactly does RunDll32 call a function, without knowing the number/types of arguments that the function can take?
Does it have a built-in compiler or something of the sort?
RunDll32 is pretty much a thin wrapper that calls LoadLibrary to load the given DLL, calls GetProcAddress to get the function address of the desired function, and then calls the function.
It can't call just any exported function in the DLL, though—it assumes that the function has a very specific function signature of the following:
void CALLBACK
EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
where CALLBACK is a macro that expands to the __stdcall calling convention. See this knowledge base article for a more detailed description.
If your DLL's function does not have the correct signature or calling convention, lots of badness will ensue. See What can go wrong when you mismatch the calling convention? for lots of gory details. Fortunately (or perhaps unfortunately), RunDll32 is written in such a way to ameliorate those types of errors, but that still doesn't mean it's a good idea. Do not use RunDll32 to call functions that do not have the correct signature. It's just a ticking time bomb waiting to go off in the next version of Windows.
It can't call just any function, it can only call function specifically written to be called. Hence, there is no magic.
I was looking through some code from the SDL library and came across a function declared like this:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Now, I'm a Delphi coder. No hablo C muy bien, senor. But I remember enough syntax from my college courses to read it like this:
Function name is WndProc. Argument list is pretty self-explanatory. Function return type is LRESULT. But what in the world is that "CALLBACK" doing there? In Delphi, any function can be used as a callback; you just need to pass the right type of function pointer. Is there any particular reason why C doesn't work that way? Or does it mean something different?
The "CALLBACK" is a calling convention. There are other kinds of calling conventions. CALLBACK is the same as __stdcall.
http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557
Some more information at Raymond Chen's blog:
https://devblogs.microsoft.com/oldnewthing/20040108-00/?p=41163
Short roundup from Raymond Chen's Blog:
The great thing about calling
conventions on the x86 platform is
that there are so many to choose from!
C calling convention (__cdecl)
The C calling convention is constrained because it allows the use of functions with a variable number of parameters. It pretty much requires that the stack be caller-cleaned and that the parameters be pushed right to left, so that the first parameter is at a fixed position relative to the top of the stack. In summary: Caller cleans the stack, parameters pushed right to left.
Pascal calling convention (__pascal)
Pascal does not support functions with a variable number of parameters, so it can use the callee-clean convention. Parameters are pushed from left to right. Nearly all Win16 functions are exported as Pascal calling convention. The callee-clean convention saves three bytes at each call point, with a fixed overhead of two bytes per function. It was also fractionally faster. On Win16, saving a few hundred bytes and a few cycles was a big deal. Note: The Fortran calling convention (__fortran) is the same as the Pascal calling convention
It's the calling convention. It's required when you pass a pointer to this function to a Windows API which later calls that function. The Windows calling convention is different from the C calling convention, therefore you need to specify to the compiler that WndProc() is special, and that it needs different startup and cleanup code.
It's a calling convention, and Delphi has them too. Try looking up 'cdecl' in the Delphi Help. In Delphi (or Object Pascal as we oldies like to call it) calling conventions come after the function declaration, like this;
function MyFunction(X, Y: Real): Real; cdecl;
To allow access to the Win32 API from a scripting language (written in C), I would like to write a function such as the following:
void Call(LPCSTR DllName, LPCSTR FunctionName,
LPSTR ReturnValue, USHORT ArgumentCount, LPSTR Arguments[])
which will call, generically, any Win32 API function.
(the LPSTR parameters are essentially being used as byte arrays - assume that they have been correctly sized to take the correct data type external to the function. Also I believe that some additional complexity is required to distinguish between pointer and non-pointer arguments but I'm ignoring that for the purposes of this question).
The problem I have is passing the arguments into the Win32 API functions. Because these are stdcall I can't use varargs so the implementation of 'Call' must know about the number of arguments in advance and hence it cannot be generic...
I think I can do this with assembly code (by looping over the arguments, pushing each to the stack) but is this possible in pure C?
Update: I've marked the 'No it is not possible' answer as accepted for now. I will of course change this if a C-based solution comes to light.
Update: ruby/dl looks like it may be implemented using a suitable mechanism. Any details on this would be appreciated.
First things first: You cannot pass a type as a parameter in C. The only option you are left with is macros.
This scheme works with a little modification (array of void * for arguments), provided you are doing a LoadLibrary/GetProcAddress to call Win32 functions. Having a function name string otherwise will be of no use. In C, the only way you call a function is via its name (an identifier) which in most cases decays to a pointer to the function. You also have to take care of casting the return value.
My best bet:
// define a function type to be passed on to the next macro
#define Declare(ret, cc, fn_t, ...) typedef ret (cc *fn_t)(__VA_ARGS__)
// for the time being doesn't work with UNICODE turned on
#define Call(dll, fn, fn_t, ...) do {\
HMODULE lib = LoadLibraryA(dll); \
if (lib) { \
fn_t pfn = (fn_t)GetProcAddress(lib, fn); \
if (pfn) { \
(pfn)(__VA_ARGS__); \
} \
FreeLibrary(lib); \
} \
} while(0)
int main() {
Declare(int, __stdcall, MessageBoxProc, HWND, LPCSTR, LPCSTR, UINT);
Call("user32.dll", "MessageBoxA", MessageBoxProc,
NULL, ((LPCSTR)"?"), ((LPCSTR)"Details"),
(MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2));
return 0;
}
No, I don't think its possible to do with without writing some assembly. The reason is you need precise control over what is on the stack before you call the target function, and there's no real way to do that in pure C. It is, of course, simple to do in Assembly though.
Also, you're using PCSTR for all of these arguments, which is really just const char *. But since all of these args aren't strings, what you actually want to use for return value and for Arguments[] is void * or LPVOID. This is the type you should use when you don't know the true type of the arguments, rather than casting them to char *.
The other posts are right about the almost certain need for assembly or other non-standard tricks to actually make the call, not to mention all of the details of the actual calling conventions.
Windows DLLs use at least two distinct calling conventions for functions: stdcall and cdecl. You would need to handle both, and might even need to figure out which to use.
One way to deal with this is to use an existing library to encapsulate many of the details. Amazingly, there is one: libffi. An example of its use in a scripting environment is the implementation of Lua Alien, a Lua module that allows interfaces to arbitrary DLLs to be created in pure Lua aside from Alien itself.
A lot of Win32 APIs take pointers to structs with specific layouts. Of these, a large subset follow a common pattern where the first DWORD has to be initialized to have the size of the struct before it is called. Sometimes they require a block of memory to be passed, into which they will write a struct, and the memory block must be of a size that is determined by first calling the same API with a NULL pointer and reading the return value to discover the correct size. Some APIs allocate a struct and return a pointer to it, such that the pointer must be deallocated with a second call.
I wouldn't be that surprised if the set of APIs that can be usefully called in one shot, with individual arguments convertable from a simple string representation, is quite small.
To make this idea generally applicable, we would have to go to quite an extreme:
typedef void DynamicFunction(size_t argumentCount, const wchar_t *arguments[],
size_t maxReturnValueSize, wchar_t *returnValue);
DynamicFunction *GenerateDynamicFunction(const wchar_t *code);
You would pass a simple snippet of code to GenerateDynamicFunction, and it would wrap that code in some standard boilerplate and then invoke a C compiler/linker to make a DLL from it (there are quite a few free options available), containing the function. It would then LoadLibrary that DLL and use GetProcAddress to find the function, and then return it. This would be expensive, but you would do it once and cache the resulting DynamicFunctionPtr for repeated use. You could do this dynamically by keeping pointers in a hashtable, keyed by the code snippets themselves.
The boilerplate might be:
#include <windows.h>
// and anything else that might be handy
void DynamicFunctionWrapper(size_t argumentCount, const wchar_t *arguments[],
size_t maxReturnValueSize, wchar_t *returnValue)
{
// --- insert code snipped here
}
So an example usage of this system would be:
DynamicFunction *getUserName = GenerateDynamicFunction(
"GetUserNameW(returnValue, (LPDWORD)(&maxReturnValueSize))");
wchar_t userName[100];
getUserName(0, NULL, sizeof(userName) / sizeof(wchar_t), userName);
You could enhance this by making GenerateDynamicFunction accept the argument count, so it could generate a check at the start of the wrapper that the correct number of arguments has been passed. And if you put a hashtable in there to cache the functions for each encountered codesnippet, you could get close to your original example. The Call function would take a code snippet instead of just an API name, but would otherwise be the same. It would look up the code snippet in the hashtable, and if not present, it would call GenerateDynamicFunction and store the result in the hashtable for next time. It would then perform the call on the function. Example usage:
wchar_t userName[100];
Call("GetUserNameW(returnValue, (LPDWORD)(&maxReturnValueSize))",
0, NULL, sizeof(userName) / sizeof(wchar_t), userName);
Of course there wouldn't be much point doing any of this unless the idea was to open up some kind of general security hole. e.g. to expose Call as a webservice. The security implications exist for your original idea, but are less apparent simply because the original approach you suggested wouldn't be that effective. The more generally powerful we make it, the more of a security problem it would be.
Update based on comments:
The .NET framework has a feature called p/invoke, which exists precisely to solve your problem. So if you are doing this as a project to learn about stuff, you could look at p/invoke to get an idea of how complex it is. You could possibly target the .NET framework with your scripting language - instead of interpreting scripts in real time, or compiling them to your own bytecode, you could compile them to IL. Or you could host an existing scripting language from the many already available on .NET.
You could try something like this - it works well for win32 API functions:
int CallFunction(int functionPtr, int* stack, int size)
{
if(!stack && size > 0)
return 0;
for(int i = 0; i < size; i++) {
int v = *stack;
__asm {
push v
}
stack++;
}
int r;
FARPROC fp = (FARPROC) functionPtr;
__asm {
call fp
mov dword ptr[r], eax
}
return r;
}
The parameters in the "stack" argument should be in reverse order (as this is the order they are pushed onto the stack).
Having a function like that sounds like a bad idea, but you can try this:
int Call(LPCSTR DllName, LPCSTR FunctionName,
USHORT ArgumentCount, int args[])
{
void STDCALL (*foobar)()=lookupDLL(...);
switch(ArgumentCount) {
/* Note: If these give some compiler errors, you need to cast
each one to a func ptr type with suitable number of arguments. */
case 0: return foobar();
case 1: return foobar(args[0]);
...
}
}
On a 32-bit system, nearly all values fit into a 32-bit word and shorter values are pushed onto stack as 32-bit words for function call arguments, so you should be able to call virtually all Win32 API functions this way, just cast the arguments to int and the return value from int to the appropriate types.
I'm not sure if it will be of interest to you, but an option would be to shell out to RunDll32.exe and have it execute the function call for you. RunDll32 has some limitations and I don't believe you can access the return value whatsoever but if you form the command line arguments properly it will call the function.
Here's a link
First, you should add the size of each argument as an extra parameter. Otherwise, you need to divine the size of each parameter for each function to push onto the stack, which is possible for WinXX functions since they have to be compatible with the parameters they are documented, but tedious.
Secondly, there isn't a "pure C" way to call a function without knowing the arguments except for a varargs function, and there is no constraint on the calling convention used by a function in a .DLL.
Actually, the second part is more important than the first.
In theory, you could set up a preprocessor macro/#include structure to generate all combinations of parameter types up to, say, 11 parameters, but that implies that you know ahead of time which types will be passed through you function Call. Which is kind of crazy if you ask me.
Although, if you really wanted to do this unsafely, you could pass down the C++ mangled name and use UnDecorateSymbolName to extract the types of the parameters. However, that won't work for functions exported with C linkage.