如何将parameter passing给DLL初始化(例如,当通过LoadLibrary加载)?

如何将parameter passing给通过LoadLibrary加载的DLL的初始化函数? 有没有可能? 没有诉诸某种导出的function或共享内存,即是。

Solutions Collecting From Web of "如何将parameter passing给DLL初始化(例如,当通过LoadLibrary加载)?"

没有直接的办法。

最简单的可能是通过环境变量。 在使用setenv调用LoadLibray之前,可以轻松设置它们,然后DLL(在同一进程中)可以使用getenv检索它们。

另一种方法

虽然我不太确定这是否属于“共享内存” (因为您也可以使用此方法将数据发送到在单独进程中加载​​的DLL) ,您可以使用VirtualAllocEx在特定地址分配一些内存,使用WriteProcessMemory传递包含DLL所需的所有数据的结构,然后在加载DLL之前用VirtualLock锁定它。

然后在DLL的入口点函数中,我将使用VirtualUnlock ,使用ReadProcessMemory获取数据,然后使用VirtualFree清理资源。

虽然有点波涛汹涌,但如果你不仅仅是一个简单的字符串传递,这是特别有用的。
请注意,您必须在目标进程中具有读取/写入权限才能使其工作。

示例 (伪代码)

 // YourApp.cpp struct DataToSend { int myInt; char myStr[320]; }; DataToSend m_data = { 1337, "This is a test string...\0" }; // ... PVOID remoteData = VirtualAllocEx( hTargetProcess, NULL, sizeof(m_data), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE ); WriteProcessMemory( hTargetProcess, remoteData, &m_data, sizeof(m_data), NULL ); VirtualLock( remoteData, sizeof(m_data) ); // Save the address (DWORD) of remoteData to the registry, to a local file, or using setenv as suggested in other answers here 

 // YourDll.cpp BOOL APIENTRY DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { DataToSend m_data = {0}; PVOID localData = /* address used in YourApp */ NULL; //... VirtualUnlock( localData, sizeof(m_data) ); ReadProcessMemory( hProcess, localData, &m_data, sizeof(m_data), NULL ); VirtualFree( localData, 0, MEM_RELEASE ); } 

另一个可能的解决方案:创建第二个DLL只显示“setparam”和“getparam”方法,而不是在应用程序(setparam)和dll的DllMain(getparam)中使用它。 在它们的基本形式中,这些方法是用静态变量实现的,但是可以使用更复杂的技术。 这个解决方案虽然稍微困难一些,但有一些优点:

  • 它不使用任何“全局”约定(除了常见DLL的名称!)

  • 它不消耗可能有限的资源(例如环境变量)

  • 这是一般的:你可以使用任何你想要的相同的DLL。

  • 它可能会像你所需要的那样强大和复杂:例如,如果需要的话,你可以使它成为线程安全的。 这只是一个执行的问题。

这是一个最小的例子:

 // The "helper" DLL // static int param; void setparam(int v) { param = v; } int getparam(void) { return param; } // The application // setparam(12345); LoadLibrary("TheDLL.dll"); // The DLL to which you want to pass parameters // BOOL WINAPI DllMain(HINSTANCE h,DWORD re,LPVOID res) { int param; switch (re) { case DLL_PROCESS_ATTACH: param = getparam(); //... 

这是“坏”和“丑陋”,但是你可以用你的电话把你的参数推入栈中,然后再按照同样的方式弹出。 一个非常黑客的解决方案,但它可以工作。 我只注意到它,因为这是可行的,不是因为这是一个很好的方法来做事情。