VC++ DLL 사용자 정의 로드, 종속 DLL 임의의 위치에서 로드

4515 단어 DLL리플렉스
자세히 보기
출처:https://blog.csdn.net/cp1300/article/details/53420444
 
여기에 반사에 관한 지식을 이야기했는데 나는 접촉한 적이 없어서 이해할 수 없지만 이것은 매우 유용하고 지식이 깊은 문장일 수 있다고 생각해서 기록해 두었다.
 
VS에서 개발한 프로그램 디렉터리에 있는 DLL을 숨기고 의존하는 DLL을 지정한 위치에 놓을 수 있습니다.
 
1. 제3자 컨트롤러를 계속 사용하고 있다. 컴파일한 후에 의존하는 컨트롤러가 모두 디렉터리를 실행하거나 시스템32 디렉터리를 실행하고 있다. 보기에 매우 불편하다. 여러 가지 방법을 찾아서 불러오는 것을 정의했는데 너무 복잡하다. 마지막에 무심결에 반사를 사용할 때 같은 DLL을 다른 곳에 두면 한 번만 불러오는 것을 발견했다. 왜냐하면 모든 dll에 유일한 KEY가 있기 때문이다. 이 방법을 이용하여 인위적으로 이런 DLL을 불러오는 것은 임의의 위치에서 불러올 수 있기 때문이다.프로그램 실행 디렉토리의 다음 DLL 파일 무더기를 해결할 수 있습니다.
이 방법은 반사 방식으로 불러오는 컨트롤에 의존하는 DLL에만 적용되며, 직접 인용된 DLL을 미리 불러올 수 없습니다.
 
 
//사용된 DLL 파일 로드 초기화

 
try

 
{

 
System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() +
"\\DLL\\DevComponents.DotNetBar2.dll");
//DLL 로드

 
System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() +
"\\DLL\\DevExpress.Data.v14.2.dll");
//DLL 로드

 
System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() +
"\\DLL\\DevExpress.Utils.v14.2.dll");
//DLL 로드

 
System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() +
"\\DLL\\DevExpress.XtraEditors.v14.2.dll");
//DLL 로드

 
System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() +
"\\DLL\\IPAddressControlLib.dll");
//DLL 로드

 
}

 
catch (System::IO::FileNotFoundException^ e)

 
{

 
System::Windows::Forms::MessageBox::Show(e->Message,
"컨트롤을 불러오는 중 오류가 발생하여 설정할 수 없습니다!"

 
System::Windows::Forms::MessageBoxButtons::OK, System::Windows::Forms::MessageBoxIcon::Error);

 
}

 
2. 직접 종속 및 참조된 DLL을 로드합니다.
CLR은 자동으로 실행 디렉터리나 시스템 32에서 DLL을 불러옵니다. 찾지 못하면 Assembly Resolve 이벤트를 터치합니다. 이 이벤트에서 필요한 DLL 파일을 불러와서 CLR에 되돌려줍니다.
 
using namespace System::Reflection;


 
Assembly^ MyResolveEventHandler(Object^ sender, ResolveEventArgs^ args);
//설명

 
[STAThreadAttribute]

 
int main(array<:string> ^args)

 
{

 
AppDomain^ currentDomain = AppDomain::CurrentDomain;

 
 

 
//컨트롤을 만들기 전에 Windows XP 시각화 사용

 
Application::EnableVisualStyles();

 
Application::SetCompatibleTextRenderingDefault(
false);

 
 

 
 

 
currentDomain->AssemblyResolve += gcnew ResolveEventHandler(MyResolveEventHandler);

 
 

 
 

 
//주 창을 만들고 실행

 
Application::Run(gcnew Form1());

 
 

 
return
0;

 
}

 
 

 
 

 
 

 
//DLL 파일이 로드되지 않은 이벤트

 
static Assembly^ MyResolveEventHandler(Object^ sender, ResolveEventArgs^ args)

 
{

 
 

 
String ^dll_name;

 
AssemblyName^ myAssemblyName =

 
gcnew AssemblyName(args->Name);

 
Console::WriteLine(
"Resolving..."+ myAssemblyName->Name);

 
dll_name = myAssemblyName->Name;

 
if (dll_name->IndexOf(
".resources") <
0)
//DLL 파일 하나에 abc와 같은 2차 이벤트가 발생합니다.dll은 처음에 abc로 DLL 확장자를 추가해야 하고 두 번째에는 abc가 필요합니다.resources, 비어 있으면 됩니다.

 
{

 
dll_name +=
".DLL";

 
}

 
else
return
nullptr;
//resources 를 비워 두면 됩니다.

 
 

 
return Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() +
"\\DLL\\"+ dll_name);

 
}

 
Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() + "\\DLL\\" + dll_name);

이것은 지정한 위치에서 DLL을 불러오는 것입니다. 사용자가 정의한 디렉터리로 바꾸거나 자원 파일에서 불러올 수 있습니다.

좋은 웹페이지 즐겨찾기