C++ c++;:将.dll加载到新进程
我们有一个基于插件的应用程序。每个插件都会导出到动态库。由于某些原因,我们必须将每个插件作为一个新进程运行(每个插件需要单独的可执行文件)。因此,我们正在尝试将.dll导出到一个新进程 每个插件都包含构造函数、析构函数和一些函数。 在不导出的情况下,它以这种方式工作得非常好(简化代码): 并在代码中使用它(再次简化): 你能看出我的错误吗?(可能无法以这种方式调用dll函数?!) 您是否知道将dll导出到新进程的更好解决方案 谢谢大家! 干杯C++ c++;:将.dll加载到新进程,c++,dll,process,C++,Dll,Process,我们有一个基于插件的应用程序。每个插件都会导出到动态库。由于某些原因,我们必须将每个插件作为一个新进程运行(每个插件需要单独的可执行文件)。因此,我们正在尝试将.dll导出到一个新进程 每个插件都包含构造函数、析构函数和一些函数。 在不导出的情况下,它以这种方式工作得非常好(简化代码): 并在代码中使用它(再次简化): 你能看出我的错误吗?(可能无法以这种方式调用dll函数?!) 您是否知道将dll导出到新进程的更好解决方案 谢谢大家! 干杯 Alex.检查例如CreateAndGetProce
Alex.检查例如
CreateAndGetProcessGodHandle()
的错误结果。CreateAndGetProcessGodHandle()创建一个新的cmd.exe实例,没有错误。因此,我们需要在每个插件中添加一个附加函数。例如,我们在插件中没有DllMain-函数,在这种情况下需要DllMain(哪个加载插件本身)?!!我不知道。
HINSTANCE lib = LoadLibrary(boost_path_to_dll);
// load the plugin class interface from the library using its factory functions
typedef fooClass *(*CreatePluginFuncDef)();
// pointer to constructor inside of plugin
CreatePluginFuncDef createPtr = (CreatePluginFuncDef)GetProcAddress(lib, "Create");
// pointer to destructor inside of plugin
typedef void(*DestroyPluginFuncDef)(fooClass*);
DestroyPluginFuncDef destroyPtr = (DestroyPluginFuncDef)GetProcAddress(lib, "Destroy");
// create new object
a = boost::shared_prt<fooClass>(pluginCreateFactoryPtr(), DestroyPluginFuncDef);
a->callSomeFunctionFromPlugin();
/**
* Run CreateProcess with specified parameters and get handle that allows
* to allocate memory and to run threads for this process.
*/
CreateAndGetProcessGodHandle(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine
)
{
HANDLE hRet = NULL;
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
TCHAR tzApplicationName[MAX_PATH] = _T("");
BOOL bRes;
// If string are empty, invalidate pointer and use the lpCommandLine.
if (lpApplicationName && !*lpApplicationName)
lpApplicationName = NULL;
else
ExpandEnvironmentStrings(lpApplicationName,
tzApplicationName,
sizeof(tzApplicationName));
bRes =
CreateProcess(*tzApplicationName ? tzApplicationName : lpApplicationName,
lpCommandLine,
NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL,
&si, &pi);
if (bRes != FALSE)
{
hRet = OpenProcess(PROCESS_CREATE_THREAD |
PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION |
PROCESS_VM_WRITE |
PROCESS_VM_READ,
TRUE,
pi.dwProcessId);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
return hRet;
}
/**
* Load DLL in another process.
*/
RemoteLoadLibrary(
HANDLE hProcess,
LPCTSTR lpFileName
)
{
LPCSTR tzLoadLibrary =
#ifdef UNICODE
"LoadLibraryW"
#else
"LoadLibraryA"
#endif
;
HMODULE hRet = NULL;
TCHAR tzFileName[MAX_PATH] = { 0 };
LPVOID lpCodeMem;
SIZE_T stCodeMem;
// Make a safe copy of the module path to be opened.
StringCbCopy(tzFileName, sizeof(tzFileName), lpFileName);
// Allocate memory in the another process.
stCodeMem = (_tcslen(tzFileName) + 1) * sizeof(TCHAR);
lpCodeMem = VirtualAllocEx(hProcess,
NULL,
stCodeMem,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (lpCodeMem != NULL)
{
// Write tzFileName in the allocated memory in the another process.
if (WriteProcessMemory(hProcess,
lpCodeMem,
tzFileName,
stCodeMem,
&stCodeMem))
{
HANDLE hThr;
DWORD dwThrId;
FARPROC fpLoadLibrary;
fpLoadLibrary =
GetProcAddress(GetModuleHandle(_T("Kernel32")), tzLoadLibrary);
// Create remote thread that loads the tzFileName module.
hThr =
CreateRemoteThread(hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)fpLoadLibrary,
(LPVOID)lpCodeMem,
0,
&dwThrId);
if (hThr != NULL)
{
// Get address where the module was loaded.
WaitForSingleObject(hThr, INFINITE);
GetExitCodeThread(hThr, (LPDWORD)&hRet);
CloseHandle(hThr);
}
}
VirtualFreeEx(hProcess, lpCodeMem, 0, MEM_RELEASE);
}
return hRet;
}
//typedef HINSTANCE HMODULE; /* HMODULEs can be used in place of HINSTANCEs */
int iRet = 0;
TCHAR tzProgPath[MAX_PATH] = _T("%ComSpec%");
TCHAR tzProgArgs[MAX_PATH] = _T("");
TCHAR tzDllPath[MAX_PATH] = _T("paht_to_my_dll");
int opt;
/** Load DLL in another process. */
HANDLE hProc;
// Start process and get handle with powers.
// Starts cmd ( do you know, how to start it hidded ?! )
hProc = CreateAndGetProcessGodHandle(tzProgPath, tzProgArgs);
// edit:
// old post: seems to work properly ( not sure about it )
// new post: hDll has value 0x59a80000{unused=???}, but should know about loaded
// plugin ( so, the problem is inside of RemoteLoadLibrary() )
HMODULE hDll = RemoteLoadLibrary(hProc, tzDllPath);
// edit:
// old post: and from here the part, which is not working ( crash by this call )
// new post: no crash, but the createPrt has value = 0
// load the plugin class interface from the library using its factory functions
typedef fooClass *(*CreatePluginFuncDef)();
// pointer to constructor inside of plugin
CreatePluginFuncDef createPtr = (CreatePluginFuncDef)GetProcAddress(hDll, "Create");
// pointer to destructor inside of plugin
typedef void(*DestroyPluginFuncDef)(fooClass*);
DestroyPluginFuncDef destroyPtr = (DestroyPluginFuncDef)GetProcAddress(hDll, "Destroy");
...