问题
This question looks like one I asked before, except that I now know that you can't call the main function from a global object. So this code doesn't work with main. But why does it fail with other functions as well?
This is the code.
.exe
main.cpp
#include "dll_class.h"
#include <iostream>
int my_main(void)
{
std::cout << "Enter the my_main code.\n";
std::getchar();
}
DllClass object(my_main);
int main(void)
{
std::cout << "Enter the main code.\n";
std::getchar();
}
.dll
dll_class.h
#include "platform.h"
#include <iostream>
class DLL_API DllClass //DLL_API is just a macro for import and export.
{
public:
DllClass(int(*main)(void))
{
std::cout << "Start application.\n";
platform = new Platform(main);
}
~DllClass(void)
{
delete platform;
}
private:
Platform* platform;
};
platform.h
class DLL_API Platform
{
public:
Platform(main_t main_tp);
~Platform(void){}
};
platform.cpp
#include "platform.h"
#include "Windows.h"
#include <iostream>
HHOOK hookHandle;
int(*main_p)(void);//This will hold a the main function of the the .exe.
LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam);
DWORD WINAPI callMain(_In_ LPVOID lpParameter)
{
std::cout << "Calling the main function.\n";
main_p();
return 0;
}
Platform::Platform(int(*main_tp)(void))
{
main_p = main_tp;
CreateThread(NULL, 0, callMain, NULL, 0, NULL);
std::cout << "Setting hooks.\n";
hookHandle = SetWindowsHookEx(WH_MOUSE_LL, keyHandler, NULL, 0);
std::cout << "Enter message loop.\n";
MSG message;
while(GetMessage(&message, (HWND)-1, 0, 0) != 0){
TranslateMessage( &message );
DispatchMessage( &message );
}
}
LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam)
{
std::cout << "Inside the hook function.\n" << std::endl;
return CallNextHookEx(hookHandle, nCode, wParam, lParam);
}
It runs great, till a certain moment. This is the output.
Start application.
Setting hooks.
Calling the main function.
Enter message loop.
Inside the hook function. (A lot of times of course).
but it never says:
Enter the my_main code.
Enter the main code.
Is it impossible to let dll call a exe function?
回答1:
The answer is still the same as the one I gave to your other question. Your Platform
constructor is hung. The loop termination conditions are never met, so the constructor never returns. And the main
function cannot run until all global objects have been constructed.
Update: The above discussion was why Enter the main code
never prints.
If you step through your my_main
function, you'll see the problem with Enter the my_main code
: The calls to cout
and getchar
are ignored. That's because the order of constructions of global objects in different translation units is unspecified. In the main executable, the object
global object is being constructed first, which means that the cin
and cout
objects may not be fully constructed. That's why cout
can't print and why getchar
cannot read.
回答2:
Surely, the CORRECT thing to do here is to construct the object
inside main
. If needed, pass in my_main
to the object. But this will solve all of the "trying to use something before it has been constructed".
The key here (which I only gather from reading the comments on the other answer) is that the cout
object is not "the same one" for the main executable and the DLL. This leads to issues with calling things that do cout
before you have entered main
[which I tried to explain in the previous question too - the C runtime library needs to initialize certain things, and that happens in an unspecified order before main
is called].
来源:https://stackoverflow.com/questions/15311934/let-a-dll-call-a-exe-function-by-sending-a-pointer