我有一个依赖.dll扩展功能(模块)的应用程序。 我想从另一个程序(这是一个服务器)中嵌入一些特定的功能。
另一个程序有一个相对简单的n-main.cpp
#include <n.h>
int main(int argc, char * argv[])
{
// creates a listen server and blocks the main thread
// until it receives SIGKILL/SIGTERM or a custom HTTP header to stop
n::start(argc,argv);
}
所以我这样做了:
#include <modulespecs.h>
#include <mymodule.h> // only some general specs
#include <n.h> // copied from n-main.cpp, no errors
// The main program calls this function to attach the module
void onModuleAttached(){
// create some fake arguments
int argc = 2;
char * argv[] = {"n.exe","someconfig.js"};
// and act as if
n::start(argc,argv);
}
到目前为止,这是完美的,服务器已创建,等待传入连接,并正确回答请求。
唯一的问题是,当加载模块时,服务器会阻止主应用程序,因此主应用程序不会继续运行,因为它等待我的模块中的服务器首先结束活动(这不是&#39发生)。即使它确实如此,服务器也有逻辑在死亡时完全关闭主应用程序。
我尝试的事情:
#include <thread>
void create_server(){
int argc = 2;
char * argv[] = {"n.exe","someconfig.js"};
// and act as if
n::start(argc,argv);
}
void onModuleAttached(){
// crashes
std::thread test(create_server);
// creates the server, then exits immediately
std::thread (create_server).join();
// same as join()
std::thread (create_server).detach();
}
有没有具体的方法来实现这一目标?
答案 0 :(得分:3)
我猜你是从onModuleLoaded()
函数调用DllMain()
。在持有OS加载程序锁定时调用DllMain()
,因此您应该never do anything scary inside DllMain()
。创建线程是一件非常可怕的事情,所以你永远不应该在DllMain()
内做到这一点。
避免这种情况的推荐方法是使用单独的DLL入口点来执行可怕的操作,然后记录您的DLL,以便在DLL初始化之后必须调用该入口点。还提供了在卸载DLL之前调用的相应出口例程。
例如:
DLLEXPORT BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
// Nothing much here
}
std::thread server_thread;
DLLEXPORT void StartServer()
{
server_thread = std::thread(create_server);
}
DLLEXPORT void StopServer()
{
server_thread.join();
}
然后您的主程序可能如下所示:
// Load the DLL and get its entry and exit routines
HMODULE serverDLL = LoadLibrary(...);
void (*StartServer)() = (void (*)())GetProcAddress(serverDLL, "StartServer");
void (*StopServer)() = (void (*)())GetProcAddress(serverDLL, "StopServer");
// Call the entry routine to start the server on a new thread
StartServer();
// Do other main program stuff
// ...
// We're done now, tell the server to stop
StopServer();
FreeLibrary(serverDLL);