我有一个依靠.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);
}

到目前为止,此方法工作完美,可以创建服务器,等待传入连接,并正确回答请求。

唯一的问题是,在加载模块时,服务器会阻止主应用程序,因此主应用程序不会继续运行,因为它会等待模块中的服务器先结束 Activity (这不会发生)。即使这样做,服务器也有逻辑在死亡时完全关闭主应用程序。

我尝试过的事情:
  #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();
  }

是否有实现此目的的特定方法?

最佳答案

我猜您正在从onModuleLoaded()函数调用DllMain()。按住OS加载程序锁定时,会调用DllMain(),因此您应该never do anything scary inside DllMain() 。创建线程是一件令人恐惧的事情,因此您永远不要在DllMain()内执行此操作。

避免这种情况的建议方法是有一个单独的DLL入口点来处理这些令人恐惧的事情,并在dllt_strong文档中添加您的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);

关于c++ - 作为.dll的一部分运行.exe的main(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21294057/

10-13 08:02