Just to experiment assembly in C++, I tried the following, which is causing the application to crash:
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
__asm {
push 5000
call Sleep
}
...
}
the assembly part of code is supposed to act like the following line
Sleep(5000);
What am I doing wrong?
edit: I am getting an Access Violation.
I just checked the assembly code in VC++ 6.
You have to call the routine like this:
call dword ptr [Sleep]
Write the code in straight in C - disassemble it, figure out what the compiler does, then you can write a correct version -
I am not x86 guy, but I think you should check the calling convention used by the compiler. It seems that Sleep cleans after it self, so maybe the compiler is inserting cleaning code also after that?
It's been a long time since I did this but I recall from the past that sometimes I had to put a single parameter in the EAX register rather than push it on the stack. Or perhaps you need to pop it off again after words if the calling convention requires it.
As Arak says, check that you are matching the compiler calling convention. Masm will force one convention, check your C compiler is enforcing the same.
Related
today I have been trying to get standard functions to work in my application such as sprintf, ect.
When ever using functions like sprintf, fgets or anything else standard my application crashes with runtime error - CRT not initialized
Current linker options:
/ignore:4098 /dll /entry:"_DllMainCRTStartup" /include:"XboxKrnlBuildNumber" /ALIGN:128,4096
Entry point:
BOOL APIENTRY DllMain(HANDLE hInstDLL, DWORD reason, LPVOID lpReserved)
Tried to init it my self by defining _CRT_INIT is an extern that takes no arguments and calling it in my DLL_PROCESS_ATTACH with no luck.
I've been stuck on this issue for months but just thought i'd come back to it and look a little deeper.
If you are doing something non-trivial in your DllMain function, this may be of help:
http://blog.barthe.ph/2009/07/30/no-stdlib-in-dllmai/
http://blogs.msdn.com/b/larryosterman/archive/2006/06/15/632502.aspx
I'm using log4cplus library. When I build application, it compiles and runs properly (well, not quite properly since it's not logging anything, but that's the other issue), but when I close it, I'm getting this error:
Run-Time Check Failure #2 - Stack around the variable 's1' was corrupted.
Here is my code. I marked relevant places with comments.
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
////////////////// SET UP CHECKS FOR MEMORY LEAKS ////////////////////
_CrtMemState s1;
_CrtMemCheckpoint(&s1);
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//////////////////////////////////////////////////////////////////////
log4cplus::PropertyConfigurator config(_T("log.properties")); // <-- this line seems to be responsible for the issue. When I remove it, everything is ok.
_CrtMemDumpAllObjectsSince(&s1); // <-- here program breaks with mentioned error.
return 1;
}
So, as written in comments, PropertyConfigurator() constructor seems to be responsible for the problem. Not any other code in this place causes the same problem.
I wonder what could be wrong if this library is used by many people and it works, while I have problems with stack corruption.
Does anyone have any idea of what's going on in here?
EDIT:
I removed all unnecessary code (the code above is edited) and left only the relevant. Still log4cplus::PropertyConfigurator config(_T("log.properties")); seems to cause the issue.
This error Run-Time Check Failure #2 is generally caused by an error somewhere in memory. After looking at the sample you provided you should change this:
log4cplus::PropertyConfigurator config(_T("log.properties"));
to this:
log4cplus::PropertyConfigurator configure(_T("log.properties"));
If that does not help then start looking at initializations of memory.
I'm using \W4 warning level on Visual Studio and I'm writing a Windows program.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
All these parameters are not used in my application, so I get warnings at compile time.
I know there are two ways of dealing with this:
Commenting parameters HINSTANCE /*hInstance*/ ...
Using the UNREFERENCED_PARAMETER macro
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
Which one is the correct one? Which one is the safer to use? Are there any problems with using the macro?
I would prefer commenting the parameters.
The macro UNREFERENCED_PARAMETER is defined in winnt.h and therefore not portable.
And if later you do reference it, you might overlook to remove the macro.
Edit: With C++17 you can now use the [[maybe_unused]] attribute. This is useful for code depending on preprocessor macros:
void foo( [[maybe_unused]] int value )
{
#ifdef USE_VALUE
useValue(value);
#endif
}
Now there won't be warnings even if USE_VALUE is undefined.
I consider the name-removing version the first to go with. It can have a disadvantage to confuse the information system so tooltip shows the crippled version. But healthy ones would use the declaration, where the names are there. (and for static and one-use things you should not have unused params, right?)
Otherwise it's matter of taste really.
In C++, both are the correct ways to handle and do not introduce any unsafe-ness directly. However, the use of UNREFERENCED_PARAMETER can cause a maintenance issue because you need to remove the use of the macro if the parameter is used in the future updates, yet compilers do not warn that situation. To audit correct use of the macro, developers have to manually inspect that the parameters are still unused.
As others pointed out, cross-platform portability could be an issue too.
In C, it is not possible to remove the parameter name; hence the macro is the reasonable solution on the Windows platform, especially in Win32 programming.
I am learning about C++ and programming to the windows api. My first "Hello Windows API" program just displays a MessageBox(). But, I have questions that the book I'm reading isn't explaining.
First, here's the program:
// HelloWin32 Program
#include<Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MessageBox(NULL, "This gets displayed in the message.", "This is the title bar of the message dialog.", MB_OK | MB_ICONEXCLAMATION);
}
This compiles and runs fine. My question has to do with the WinMain() declaration that says int WINAPI WinMain(...). As I read it, the WinMain function (method?) returns an integer. But what does WINAPI communicate?
Obviously, I'm writing to the Windows API. Does WINAPI somehow flag the function so the program uses Windows API to execute it or something?
WINAPI is a preprocessor definition defined as __stdcall, a calling convention; when functions have __stdcall before their name, it is a directive to the compiler to make the function use that calling convention. This is so both your function and the function calling your function agree to use the stdcall calling convention and the call executes correctly.
This is necessary because the default calling convention of your compiler may or may not be stdcall, so you have to explicitly tell the compiler to make it that way for that function. The designers of the Windows API decided, mainly for compatibility reasons and the universality of the stdcall calling convention, to make all function calls use the stdcall calling convention.
Also, you can have functions with different calling conventions being used in the same program. So for instance, WinMain has to be stdcall but the other functions of your program do not; they can use the compiler default.
A calling convention is a method for doing things like the order in which parameters should go on the stack, who should remove them from the stack when the function returns, where to put return values, and other things. Different calling conventions do this in different ways. Above all, it is extremely important that both the caller and the callee follow the same calling convention. For more info on calling conventions, see the Wikipedia article.
For example:
int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
WINAPI is a a define that looks like this:
#define WINAPI __stdcall
why can't you just do:
int __stdcall WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
actually I think my problem is that I'm sort of confusing defines with typedef's. Can someone explain this to me? what does the define do and why can't you just write __stdcall in its place?
Because the WINAPI calling convention is not guaranteed to be __stdcall. Code that uses WINAPI will still be correct even when it isn't.
You can write the function as in your latter example, and it'd work fine - it's just not good practice and would not be portable to a platform where the calling convention is something else.
This was originally done during the switchover from 16-bit to 32-bit code. In the 16-bit version of <windows.h> it was:
#define WINAPI __pascal
WINAPI let you compile for either without modifying the source code. Of course, 16-bit Windows is no longer a factor (at least for most people), but it's still not worth changing all the source code to use __stdcall directly (especially since it could change again someday).
You can just write __stdcall in its place, but don't. They've seen fit to #define WINAPI to __stdcall to make that opaque, which is just good programming practice.
Also, back in the day, some Windows libraries used Pascal calling convention and other libraries used C convention. A preprocessor define helped gloss over that.
Because WINAPI is a macro (well a #define anyway) it can be "pre-processed" to mean something else or even nothing at all.
That means you can write more portable code, as you can put in WINAPI when it is required by Win32 to mean __stdcall but, or if it is required in another environment to mean something else or nothing.