C++/CLI: Use LoadLibrary + GetProcAddress with an exe
Up until now, I had some sort of plugin mechanism in which I loaded dlls using LoadLibrary and GetProcAddress to create a concrete object and return a common interface. This worked fine until I decided that one of the dlls should be an exe.
LoadLibrary's documentation says that it can be used for exe's as well, so I gave it a shot. The exe gets loaded without errors, as GetProcAddress. But when I try to call my concrete object's constructor, I get an access violation.
I thought this would happen because loading an exe does not load all the dlls it uses. So I tried loading them using LoadLibrary, but I got the same error. Any advice on this?
Here's my code (mixed C++/CLI):
Interface* MCFactory::LoadInstanceFromAssembly( String ^ concreteAssemblyName, String ^ param ){
string fullPathToAssembly = "";
fullPathToAssembly += FileSystem::GetPathToProgramDirectory();
fullPathToAssembly += "\\" + marshal_as<string>(concreteAssemblyName);
MODULE hDLL = AssemblyLoader::GetInstance().LoadAssembly( fullPathToAssembly );
Interface* pObject = NULL;
if (hDLL != NULL){
t_pCreateInstanceFunction pCreateInstanceFunction =
(t_pCreateInstanceFunction) ::GetProcAddress (hDLL, CREATE_INSTANCE开发者_JS百科_FUNCTION_NAME.c_str());
if ( pCreateInstanceFunction != NULL ){
//Yes, this assembly exposes the function we need
//Invoke the function to create the object
pObject = (*pCreateInstanceFunction)( marshal_as<string>(param) );
}
}
return pObject;
}
(AssemblyLoader::GetInstance().LoadAssembly is just a wrapper for ::LoadLibrary)
You can use LoadLibrary
and GetProcAddress
on the main executable for your process, this allows dynamic exports in the reverse direction (.exe to .dll).
You cannot load a second .exe into your process memory space, except for access to resources/data, because .exe code is not relocatable. (Pure MSIL .exe files are an exception, because there is no code in the file, it's all generated by the JIT.)
Basically, LoadLibrary
on a .exe is useful only when
The .exe is the main process exe, in which case you might as well use
GetModuleHandle
or
The
LOAD_LIBRARY_AS_DATAFILE
flag is used
It is possible.
http://www.codeproject.com/Articles/1045674/Load-EXE-as-DLL-Mission-Possible
The idea is to patch the IAT, then call the CRT. Of course, the EXE must be relocatable, and by default (ASLR) it is.
Whilst Ben's answer covers most cases this article http://sandsprite.com/CodeStuff/Using_an_exe_as_a_dll.html may be useful in some circumstances
精彩评论