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
Related
I'm trying to provide my own entry point to a visual c++ executable using the linker switch "/entry". The associated Microsoft documentation goes into some detail about how to manually initialise the c runtime in a dll, but I can't grasp how to initialise it in my exe. The best I've got is that I need to call _CRT_init, but I don't know if that's a function or a macro, or where it might be defined, and Visual Studio (and msbuild) don't recognise the identifier, so no hints there.
The rationale here is that I'm attempting to unit test, with Google Test, an executable, and it won't link because main() clashes. The two approaches mentioned in the GTest FAQ aren't really generalisable and would require considerable rework to about 30 legacy executables to implement. Renaming each unit test application's main() seems like a super-easy approach, if only I could initialise the c runtime.
So I searched through the C Runtime source this afternoon, and the answer is "no". You cannot provide your own executable entry point not named main if you want to use the C Runtime. Quite aside from _CRT_INIT() being the an initialisation function for a dll (mainCRTStartup() is one of the initialisation functions for executables), mainCRTStartup() and its like call main() by name.
You could initialize the CRT in a standalone wrapper module which has
main; obj1
Rename the main of all existing exe modules to xx_main; obj2, obj3.... objn
Link obj1 (main) with (obj2, obj3.... objn).
To test a foo.cc file, you need to compile and link it into your unit
test program
What's the issue with this scheme ?
Though not specifically documented, it is possible to initialize the CRT in an executable in the same way it can be done in a DLL.
EXTERN_C BOOL WINAPI _CRT_INIT( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved );
// ThreadProc for CreateRemoteThread, a possible use case.
DWORD WINAPI ArbitraryAlternateEntryPoint( LPVOID )
{
_CRT_INIT( GetModuleHandle( NULL ), DLL_PROCESS_ATTACH, NULL );
// CRT functions can be used here.
_CRT_INIT( GetModuleHandle( NULL ), DLL_PROCESS_DETACH, NULL );
return 0;
}
The documentation suggests that _CRT_INIT should be called for each new thread in addition to the initial call, but in practice this is not necessary.
Is it possible to create a function in a shared library (.dll on Windows, and .so on linux) that is executed right when the library is loaded (or unloaded)?
Just like the main() function is the entry point for an executable, can I define a function to execute when the DLL is loaded, or unloaded?
E.g.:
void _atstart()
{
// Initialize some stuff needed by the library
}
void _atexit()
{
// Release some allocated resources
}
I think I've seen such an example somewhere, but I couldn't find it any more, and couldn't find anything on the internet about this.
If it is of any use, I'm compiling the code with MinGW.
In C++ you can at least create a global instance of some class
class ResourceHolder {
public:
ResourceHolder() {
// at start
}
~ResourceHolder() {
// at exit
}
};
ResourceHolder theHolder;
Some awareness is required though if you use another global variables in your library.
For windows you can use DllMain:
BOOL WINAPI DllMain(
__in HINSTANCE hinstDLL,
__in DWORD fdwReason,
__in LPVOID lpvReserved
);
The second parameter fdwReason specifies if the library is loaded or unloaded. Full reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// code for library load
break;
case DLL_PROCESS_DETACH:
// code for library unload
break;
}
return (TRUE);
}
For Linux you might be able to use:
__attribute__ ((constructor))
__attribute__ ((destructor))
but this only came up after a google search, so you have to investigate by yourself - http://tdistler.com/2007/10/05/implementing-dllmain-in-a-linux-shared-library
As it has been said, under Window you can work from DllMain. But be careful what you will do since there is a lot of restrictions (use of COM CoInitialize function is forbidden, for instance). One thing you can't rely on is that there is no guaranty in what order dll will be loaded/unloaded, so you must not call functions from your DllMain that resides in an other of your dll : it can works today, but not tomorrow :)
More online on the MSDN :
[http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx]
Patrice
Under Windows you can write your own version of DllMain().
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.
I've got a function imported from a DLL. I control the source of both the host executable and the dynamic library. Now, in DLLMain then I used MessageBox to pop up the address of the function I'm exporting, and compared it using a breakpoint to the function pointer returned by GetProcAddress, and they're identical.
However, when I try to call the function, I get an access violation. The function in question just returns NULL and has no logic, so it can't be thrown by the function specifically.
How can calling a known valid function pointer, with the correct signature, and verified safe logic, yield an access violation?
Edit: Information gained through another separate question about why the debugger is dying in this situation suggests that my stack is being smashed too? That would make more sense than an AV, but the function pointer and the function are completely compatible and the address is correct.
extern "C" Render* __cdecl CreateRender(WindowsOS* ptr) {
return nullptr;
}
typedef Render*(__cdecl *RendererCreateFunction)(WindowsOS*);
I used a simple, small piece of code in DLLMain to qualify that they are in fact compatible as far as the compiler is concerned.
BOOL WINAPI DllMain(
__in HINSTANCE hinstDLL,
__in DWORD fdwReason,
__in LPVOID lpvReserved
) {
RendererCreateFunction func = &CreateRender;
}
If they aren't compatible (they include the same header) then the compiler should throw an error and refuse to build the DLL, but it accepts this just fine.
If this is DLLMain you use in your code then it has no return statement and most likely returns a not initialized value, quite probably 0 as a good main function, which effectively unloads the DLL from the memory. Make sure DLLMain returns TRUE.
I completely failed this one. Wrote a class that manages a resource without respecting my move and copy semantics properly. Turns out that I was calling FreeLibrary() on the library in question mistakenly before I needed to use it.