DLL을 과연 언제 delay loaded 방식으로 처리하는 것이 좋을까요?
첫 번째 이유는, 당연히 최초 Application의 로딩 속도를 빠르게 하고 싶어서입니다. 이건 너무나 당연한 것이라서 더 이상 설명의 여지가 없지요.
두 번째 이유는, 다중 환경을 지원하기 위해서 delay loaded 방식을 사용할 수 있습니다. 음... 다중 환경이라... 예를 한번 들어볼까요?
TestMethod라는 Win32 API가 Windows XP 이상에만 포함된 Test.DLL 파일에만 구현되어 있다고 해봅시다. 그런 경우, Test.lib에 링크를 해버리면 해당 프로그램은 Windows 98에서는 실행조차 할 수가 없게 되지요. 만약 개발자가, Win98에서는 해당 기능을 사용하려고 할 때에 불가능하다는 메시지를 띄우게 하고, WinXP 이상인 경우에는 정상적으로 사용하도록 프로그램하고 싶다면!
바로 그럴 때, delay loaded 방식으로 Test.DLL과 링크를 시켜주면 됩니다. 다음과 같은 식이면 좋겠지요.
if (IsWin98() == true)
{
MessageBox(NULL, "WinXP 이상에서만 사용할 수 있습니다.", NULL, MB_OK);
} else {
TestMethod();
}
물론, GetProceAddress / LoadLibrary를 사용한 방법도 있는데, 그런 경우에는 호출이 delay loaded DLL 방식보다 더 복잡하게 되지요. 소스의 간결성 차원에서라도 바람직한 방법은 아닙니다.
자, 이제 그럼 어떻게 Delay Loaded 방식으로 링크할 수 있을까요?
경우의 수는 여러 가지가 있겠지만, 제가 주로 사용하는 틀은 다음과 같습니다.
VS.NET 2005의 경우.
: 소스
#pragma comment( lib, "Test.lib" )
: 프로젝트 속성
좌측 트리에서 Configuration Properties / Linker / Input을 선택하면 우측 리스트 박스에 Delay Loaded DLLs 항목이 나옵니다. 거기에 "Test.dll"이라고 추가해 주면 됩니다.
그리 어렵지 않지요. ^^ 사실, delay loaded 방식에 대해서 소개된 지는 오래되었지만. 이제서야 한번 실제 적용을 해보게 되는군요. ^^
이외에도 다음의 토픽을 함께 봐두시는 것도 좋을 것 같아서 링크를 적어봅니다.
Explicitly Unloading a Delay-Loaded DLL :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vcconexplicitlyunloadingdelay-loadeddll.asp
Loading All Imports for a Delay-Loaded DLL:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vclrfLoadingAllImportsForDelayLoadedDLL.asp
Changes in the DLL Delayed Loading Helper Function Since Visual C++ 6.0 :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vchowChangesInHelperFunctionFromVisualC60.asp
| Title |
| 11901 | 정성태 | 5/21/2019 | 27140 | 오류 유형: 538. msbuild 오류 - Could not find a part of the path '%LOCALAPPDATA%\Temp\2\.NETFramework,Version=v4.0.AssemblyAttributes.cs' | |
| 11900 | 정성태 | 5/18/2019 | 25938 | 오류 유형: 537. "sfc /scannow" 실행 중 시스템이 부팅되는 현상 | |
| 11899 | 정성태 | 5/17/2019 | 25899 | Linux: 9. Linux에서 윈도우의 OutputDebugString 대신 사용할 수 있는 syslog [1] | |
| 11898 | 정성태 | 5/16/2019 | 27264 | VC++: 130. C++ string의 c_str과 data 함수의 차이점 [3] | |
| 11897 | 정성태 | 5/16/2019 | 32844 | 오류 유형: 536. Visual Studio - "Developer Pack"을 설치했는데도 "대상 프레임워크" 목록에 나오지 않는 경우 [2] | |
| 11896 | 정성태 | 5/15/2019 | 30551 | 개발 환경 구성: 440. C#, C++ - double의 Infinity, NaN 표현 방식 | 1 |
| 11895 | 정성태 | 5/12/2019 | 27039 | .NET Framework: 832. ML.NET Model Builder - 회귀(Regression), 다중 분류(Multi-class classification) 예제 | 1 |
| 11894 | 정성태 | 5/10/2019 | 29227 | VS.NET IDE: 135. Visual Studio - ML.NET Model Builder 소개 [5] | |
| 11893 | 정성태 | 5/10/2019 | 24677 | 오류 유형: 535. C# 6.0 이상의 문법을 컴파일 시 오류가 발생한다면? | |
| 11892 | 정성태 | 5/10/2019 | 23859 | 웹: 38. HTTP Cookie의 expires 시간 형식(RFC7231) | |
| 11891 | 정성태 | 5/9/2019 | 27935 | .NET Framework: 831. (번역글) .NET Internals Cookbook Part 12 - Memory structure, attributes, handles | |
| 11890 | 정성태 | 5/8/2019 | 24507 | 개발 환경 구성: 439. "Visual Studio Enterprise is required to execute the test." 메시지와 관련된 코드 기록 | |
| 11889 | 정성태 | 5/8/2019 | 23191 | 개발 환경 구성: 438. mstest, QTAgent의 로그 파일 설정 방법 | |
| 11888 | 정성태 | 5/8/2019 | 42571 | .NET Framework: 830. C# - 비동기 호출을 취소하는 CancellationToken의 간단한 예제 코드 [1] | 1 |
| 11887 | 정성태 | 5/8/2019 | 28098 | .NET Framework: 829. C# - yield 문을 사용할 수 있는 메서드의 조건 | |
| 11886 | 정성태 | 5/7/2019 | 24825 | 오류 유형: 534. mstest.exe 실행 시 "Visual Studio Enterprise is required to execute the test." 오류 [2] | |
| 11885 | 정성태 | 5/7/2019 | 22808 | 오류 유형: 533. mstest.exe 실행 시 "File extension specified '.loadtest' is not a valid test extension." 오류 발생 | |
| 11884 | 정성태 | 5/5/2019 | 27244 | .NET Framework: 828. C# DLL에서 Win32 C/C++처럼 dllexport 함수를 제공하는 방법 - 두 번째 이야기 | |
| 11883 | 정성태 | 5/3/2019 | 32913 | .NET Framework: 827. C# - 인터넷 시간 서버로부터 받은 시간을 윈도우에 적용하는 방법 | 1 |
| 11882 | 정성태 | 5/2/2019 | 29279 | .NET Framework: 826. (번역글) .NET Internals Cookbook Part 11 - Various C# riddles | 1 |
| 11881 | 정성태 | 4/28/2019 | 29570 | 오류 유형: 532. .NET Core 프로젝트로 마이그레이션 시 "CS0579 Duplicate 'System.Reflection.AssemblyCompanyAttribute' attribute" 오류 발생 | |
| 11880 | 정성태 | 4/25/2019 | 25714 | 오류 유형: 531. 이벤트 로그 오류 - Task Scheduling Error: m->NextScheduledSPRetry 1547, m->NextScheduledEvent 1547 | |
| 11879 | 정성태 | 4/24/2019 | 35391 | .NET Framework: 825. (번역글) .NET Internals Cookbook Part 10 - Threads, Tasks, asynchronous code and others | 2 |
| 11878 | 정성태 | 4/22/2019 | 29352 | .NET Framework: 824. (번역글) .NET Internals Cookbook Part 9 - Finalizers, queues, card tables and other GC stuff | 1 |
| 11877 | 정성태 | 4/22/2019 | 30178 | .NET Framework: 823. (번역글) .NET Internals Cookbook Part 8 - C# gotchas | 1 |
| 11876 | 정성태 | 4/21/2019 | 26201 | .NET Framework: 822. (번역글) .NET Internals Cookbook Part 7 - Word tearing, locking and others | 1 |