What exactly does this line of code mean? - c++

I saw this line of code in a source code and I simply can't understand what its meaning is even after having searched around (I don't know what exactly to search for). Can someone explain what this is for or where I can read up on it?
using f_loadLibraryA = HINSTANCE(WINAPI*)(const char* lpLibFilename);
Sorry for such a dumb question...

f_loadLibraryA becomes a type (almost like a typedef) for a function that takes a const char* as its single parameter and has a return type of HINSTANCE.
WINAPI is a #define macro that maps to a calling convention, which is not part of the C++ standard, but exists to establish how the function should be called (how parameters are loaded onto the call stack, and other low level things like that). It's usually either __stdcall or __cdecl.

It declares f_loadLibraryA to be a type alias for HINSTANCE(WINAPI*)(const char* lpLibFilename).
See also: https://en.cppreference.com/w/cpp/language/type_alias

Related

what does this "int logprintf( const char* ptr, ... )" do?

I have an old C++ code that has this line of code:
int logprintf( const char* ptr, ... );
and I am not sure what does it do exactly? should I change the code in order to be able to compile the code with new versions of the compiler?! does anybody have an idea? any help would be appreciated.
That's just C code and any compiler made since the 1980s should be able to handle it. The definition is of a varidic function, or "varargs" in C parlance.
What that does is declare a method signature, nothing more. Presumably somewhere else, either in a library you link in or in a C or C++ file you compile there's a matching implementation.
Most printf-style functions do not have a fixed number of arguments. This is what the ellipsis ... represents, zero or more arbitrary arguments go there.

c++ va_arg typecast issue

All,
I am writing a small c++ app and have been stumped by this issue. Is there a way to create (and later catch ) the error while accessing element from va_list macro using va_arg if element type is not expected. Eg:-
count=va_arg(argp,int);
if (count <= 0 || count > 30)
{
reportParamError(); return;
}
Now, if I am passing a typedef instead of int, I get garbage value on MS compiler but 95% of time count gets value 0 on gcc (on 64 bit sles10 sys). Is there a way I can enforce some typechecking, so that I get an error that can be caught in a catch block?
Any ideas on this would be very helpful to me. Or is there a better way to do this. The function prototype is:-
void process(App_Context * pActx, ...)
The function is called as
process(pAtctx,3,type1,type2,type3);
It is essential for pActx to be passed as 1st parameter and hence cannot pass count as 1st parameter.
Update-1
Ok, this sounds strange but nargs does not seem to part of va_list on sles10 gcc. I had to put in
#ifdef _WIN32
tempCount=va_arg(argp,int)
#endif
After using this, parameters following nargs do not get garbage values. However, this introduces compiler/platform based #ifdefs....Thanks Chris and Kristopher
If you know a count will always be passed as the second argument, then you could always change the signature to this:
void process(App_Context * pActx, int count, ...)
If that's not an option, then there is really no way to catch it. That's just how the variable-argument-list stuff works: there is no way for the callee to know what arguments are being passed, other than whatever information the caller passes.
If you look into how the va_arg macro and related macros are implemented, you may be able to figure out how to inspect all the stuff on the stack. However, this would not be portable, and it is not recommended except as a debugging aid.
You also might want to look into alternatives to variable-arguments, like function overloading, templates, or passing a vector or list of arguments.
No, there is no way. varargs doesn't provide any way to check the types of parameters passed in. You must only read them with the correct type which means that you need another way of communicating type information.
You are likely to be better off avoiding varargs functionality unless you really need it. It's only really a C++ feature for the sake of legacy functions such as printf and friends.

ESP Error when I call an API function?

platform : win32 , language : c++
I get this error when I call an imported function I declared:
Run-Time Check Failure #0 - The value of ESP was not properly saved
across a function call. This is
usually a result of calling a function
declared with one calling convention
with a function pointer declared with
a different calling convention.
And this is the code I used:
int LoadSongFromFile(int module);
typedef int (CALLBACK* loadSongT)(LPCTSTR);
//...
HINSTANCE dllHandle = NULL;
loadSongT loadSongPtr = NULL;
dllHandle = LoadLibrary(L"miniFMOD.dll");
loadSongPtr = (loadSongT)GetProcAddress(dllHandle,"SongLoadFromFile");
int songHandle = loadSongPtr(L"C:\b.xm");
The function I'm trying to call is SongLoadFromFile which requires one argument (in C# it is string so I assume its LPCTSTR in C++) and returns an int value.
Can somebody check what have I done wrong?
P.S. songHandle gets a weird negative value of -858993460
This is how I can call that function from C# :
[DllImport("MiniFMOD.dll")] public static extern int SongLoadFromFile(string name);
P.S. 2 : Using *typedef int (__cdecl loadSongT)(char);* doesn't return an error but songHandle comes up as 0.
miniFMOD.dll is an unmanaged library
I think the other people are misunderstanding the question. It seems to me that minifmod.dll is a native library that exports a function named SongLoadFromFile. The existing code that calls this is managed code (C#) that uses DllImport to call the function in the native DLL. From what little information I could gather by a few Google searches, it looks as though it should be declared as follows:
typedef int (__cdecl * SongLoadFromFileT)(const char*);
Importantly, it is __cdecl calling convention and it takes an ANSI string instead of a Unicode string.
As an aside, I find it strange that I can't find ANYTHING on minifmod.dll other than a few forum posts on a Russian website and some SO questions from this guy. The only "legitimate" information I can find on minifmod is a small static library with similar functionality. I wonder if minifmod.dll is some kind of commercialized version of the static library; at least that would explain why there is not much public documentation about it.
Ah, I found it; it is a Delph port of minifmod (http://www.cobans.net/minifmod.php).
You need to make sure to specify the right calling convention in your function pointer prototype ('CALLBACK' might be the wrong choice).
The calling code uses the calling convention not matching that of the function being called. See this very similar question. You need to open the header defining that function (should come with the library you try to use), look the convention up and change your function pointer declaartion accordingly.

Function pointers and unknown number of arguments in C++

I came across the following weird chunk of code.Imagine you have the following typedef:
typedef int (*MyFunctionPointer)(int param_1, int param_2);
And then , in a function , we are trying to run a function from a DLL in the following way:
LPCWSTR DllFileName; //Path to the dll stored here
LPCSTR _FunctionName; // (mangled) name of the function I want to test
MyFunctionPointer functionPointer;
HINSTANCE hInstLibrary = LoadLibrary( DllFileName );
FARPROC functionAddress = GetProcAddress( hInstLibrary, _FunctionName );
functionPointer = (MyFunctionPointer) functionAddress;
//The values are arbitrary
int a = 5;
int b = 10;
int result = 0;
result = functionPointer( a, b ); //Possible error?
The problem is, that there isn't any way of knowing if the functon whose address we got with LoadLibrary takes two integer arguments.The dll name is provided by the user at runtime, then the names of the exported functions are listed and the user selects the one to test ( again, at runtime :S:S ).
So, by doing the function call in the last line, aren't we opening the door to possible stack corruption? I know that this compiles, but what sort of run-time error is going to occur in the case that we are passing wrong arguments to the function we are pointing to?
There are three errors I can think of if the expected and used number or type of parameters and calling convention differ:
if the calling convention is different, wrong parameter values will be read
if the function actually expects more parameters than given, random values will be used as parameters (I'll let you imagine the consequences if pointers are involved)
in any case, the return address will be complete garbage, so random code with random data will be run as soon as the function returns.
In two words: Undefined behavior
I'm afraid there is no way to know - the programmer is required to know the prototype beforehand when getting the function pointer and using it.
If you don't know the prototype beforehand then I guess you need to implement some sort of protocol with the DLL where you can enumerate any function names and their parameters by calling known functions in the DLL. Of course, the DLL needs to be written to comply with this protocol.
If it's a __stdcall function and they've left the name mangling intact (both big ifs, but certainly possible nonetheless) the name will have #nn at the end, where nn is a number. That number is the number of bytes the function expects as arguments, and will clear off the stack before it returns.
So, if it's a major concern, you can look at the raw name of the function and check that the amount of data you're putting onto the stack matches the amount of data it's going to clear off the stack.
Note that this is still only a protection against Murphy, not Machiavelli. When you're creating a DLL, you can use an export file to change the names of functions. This is frequently used to strip off the name mangling -- but I'm pretty sure it would also let you rename a function from xxx#12 to xxx#16 (or whatever) to mislead the reader about the parameters it expects.
Edit: (primarily in reply to msalters's comment): it's true that you can't apply __stdcall to something like a member function, but you can certainly use it on things like global functions, whether they're written in C or C++.
For things like member functions, the exported name of the function will be mangled. In that case, you can use UndecorateSymbolName to get its full signature. Using that is somewhat nontrivial, but not outrageously complex either.
I do not think so, it is a good question, the only provision is that you MUST know what the parameters are for the function pointer to work, if you don't and blindly stuff the parameters and call it, it will crash or jump off into the woods never to be seen again... It is up to the programmer to convey the message on what the function expects and the type of parameters, luckily you could disassemble it and find out from looking at the stack pointer and expected address by way of the 'stack pointer' (sp) to find out the type of parameters.
Using PE Explorer for instance, you can find out what functions are used and examine the disassembly dump...
Hope this helps,
Best regards,
Tom.
It will either crash in the DLL code (since it got passed corrupt data), or: I think Visual C++ adds code in debug builds to detect this type of problem. It will say something like: "The value of ESP was not saved across a function call", and will point to code near the call. It helps but isn't totally robust - I don't think it'll stop you passing in the wrong but same-sized argument (eg. int instead of a char* parameter on x86). As other answers say, you just have to know, really.
There is no general answer. The Standard mandates that certain exceptions be thrown in certain circumstances, but aside from that describes how a conforming program will be executed, and sometimes says that certain violations must result in a diagnostic. (There may be something more specific here or there, but I certainly don't remember one.)
What the code is doing there isn't according to the Standard, and since there is a cast the compiler is entitled to go ahead and do whatever stupid thing the programmer wants without complaint. This would therefore be an implementation issue.
You could check your implementation documentation, but it's probably not there either. You could experiment, or study how function calls are done on your implementation.
Unfortunately, the answer is very likely to be that it'll screw something up without being immediately obvious.
Generally if you are calling LoadLibrary and GetProcByAddrees you have documentation that tells you the prototype. Even more commonly like with all of the windows.dll you are provided a header file. While this will cause an error if wrong its usually very easy to observe and not the kind of error that will sneak into production.
Most C/C++ compilers have the caller set up the stack before the call, and readjust the stack pointer afterwards. If the called function does not use pointer or reference arguments, there will be no memory corruption, although the results will be worthless. And as rerun says, pointer/reference mistakes almost always show up with a modicum of testing.

Why does strlen() appear to return <void> in the VC++ debugger? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 14 years ago.
Improve this question
I have a string in C++ of type const char* passed as argument to strlen, but it returns void.
it goes like
strlen(astruct.string);
Thanks..
EDIT: Did some checking,
strlen("test");
still gives void.. why?
EDIT: Here's the image
http://img14.imageshack.us/img14/1808/strlen.png
Sorry for being unclear previously. Formatting was not working quite well. Anyway, the confusion was solved by both Evan Teran and Vlad Romascanu. Also take a look at Brian R. Bondy's answer.
Thanks. Feel free to close.
You are confused by the crappy debugger of visual studio 6.0. Don't rely on this. It likely couldn't get the return value due to inlining or something similar.
Print the value out to get the real value.
EDIT: Also, from your example, it seems that you may not be storing the result of strlen anyway. This also may be a reason why the debugger isn't seeing the return value. It's entirely possible that the compiler decided that it doesn't need to actually execute the strlen if you aren't using the value.
NOTE: at this point there is no real excuse for still using VC++ 6.0. It is an ancient compiler and IDE which is an embarrassingly poor c++ compiler. The newer versions of the visual c++ compiler are free (without the IDE), use them.
strlen is not of return type void, it's your debugger that is not giving the right message.
Why your debbuger is showing void?
The implementation of strlen that you are using is probably wrapped around a #define strlen someothername_strlen.
The debugger probably does not support #define properly or some other modifiers on the function.
You will have to do something like iLen = strlen("test") then check iLen in your watch.
Normally you can call functions in your watch. For example try to define the following function then call it in your watch:
int testFunc(char*)
{
return 5;
}
You will probably get 5 in your watch as a result.
Referring to your screen shot: your debugger is displaying <void> for strlen(...) when in fact it should display an error.
You cannot call methods and display their results in the debugger watch. The debugger will only display existing variables and data. It cannot invoke arbitrary methods on demand since the methods can alter the state of the program being debugged in ways that were not anticipated by either the author of the code nor by the debugger.
What you can do is, in your code, temporarily add:
size_t tmp_len = strlen(struc.string);
then compile, and add tmp_len to the watch.
strlen returns an integer, so I assume you mean it returns "0".
Also, the way that you specify your data type, I can't quite tell if it's a const char * or const char **. If it's the latter, then you need to make sure you're dereferencing the ** to a single *.
My guess is that the string starts with a null byte, which is why it's returning 0.
In C++, functions always return a value of the type they are declared to return. Since the strlen function declaration looks something like this:
size_t strlen(const char *);
the only thing it can possibly return is a size_t. The compiler uses this information at compile time to determine how to handle the return value when you call the function. The point here is that if the strlen function is declared as above, it cannot decide to return void sometimes and a value of type size_t other times.
This is generally a characteristic of statically typed languages like C++. In dynamically typed languages (Perl, Python, Ruby, PHP, etc) a function can decide to return a value of any type each time it is called.
It can't return void. Void is the lack of a return value, so you can't, err, return it.
How do you check for void anyway? Void isn't a value. Please demonstrate how you are getting void. Is it compile time or run time?
If you do in fact have a system where strlen is declared with a void return type, run as fast as you can in the other direction.