如何通过LoadLibrary加载的DLL传递参数给初始化函数?这是否可能?而且不使用某种导出函数或共享内存。
没有直接的方法。
最简单的方法可能是通过环境变量。在调用 LoadLibrary
之前,可以使用 setenv
轻松设置它们,然后 DLL(在同一进程中)可以使用 getenv
检索它们。
// 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();
//...
一种替代方法
虽然我不确定这是否属于"共享内存"(因为您还可以使用此方法将数据发送到在单独进程中加载的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 );
}
这种方法很“糟糕”和“丑陋”,但是在进行调用之前,您可以使用内联汇编将参数推送到堆栈上,并以类似的方式将它们弹出。这是一种非常hack-ish的解决方案,但它确实可行。我只是提到它是因为它是可能的,而不是因为这是一个好的做事方式。
LoadLibrary
调用和实际调用DllMain
之间栈帧的大小是多少。 - Adam Rosenfield