Visual Studio에서 링커 오류 LNK1107 해결하기

서론

Visual Studio로 프로젝트를 개발하다 보면 다양한 링커 오류에 직면하게 됩니다. 그 중에서도 LNK1107 오류는 특히 모듈과 DLL을 관리하는 과정에서 자주 발생하는 오류입니다. 이 글에서는 LNK1107 오류의 원인과 효과적인 해결 방법을 자세히 알아보겠습니다.

LNK1107 오류란?

LNK1107 오류는 다음과 같은 메시지로 나타납니다:

잘못 되었거나 손상 된 파일: 위치에서 읽을 수 없습니다

또는 영문으로:

LNK1107: invalid or corrupt file: cannot read at 0x...

이 오류는 주로 링커가 처리할 수 없는 형식의 파일을 처리하려고 할 때 발생합니다. 예를 들어, DLL 파일을 링크 과정에서 직접 .obj 파일처럼 취급하려고 할 때 발생할 수 있습니다.

주요 발생 원인

  1. DLL 파일을 직접 링크하려는 시도: 가장 흔한 원인은 .dll 파일을 직접 링커에 전달하는 것입니다. 링커는 .obj 파일을 기대하는데 .dll 파일을 받게 되면 오류가 발생합니다.
  2. CLR 모듈 처리 오류: /clr:noAssembly 또는 /NOASSEMBLY 옵션으로 생성된 .dll 또는 .netmodule 파일을 링커에 직접 전달할 때 발생합니다.
  3. 손상된 라이브러리 파일: 라이브러리 파일이 손상되었거나 링커가 기대하는 형식이 아닐 때 발생할 수 있습니다.
  4. 호환되지 않는 컴파일러 버전: 다른 버전의 Visual Studio나 컴파일러로 생성된 파일을 링크하려고 할 때 발생할 수 있습니다.

해결책

1. .obj 파일을 사용하기

LNK1107 오류의 대부분의 경우, 다음과 같은 해결책이 효과적입니다:

LNK1107.dll 대신 LNK1107.obj를 링크에 사용하세요.

이는 Microsoft 공식 문서에서도 권장하는 방법입니다. DLL 자체를 링크하지 말고, DLL을 만드는 데 사용된 .obj 파일을 링크하세요.

2. lib 파일 사용하기

DLL을 링크하려면 해당 DLL의 임포트 라이브러리(.lib)를 사용해야 합니다:

dll 대신 obj나 lib 등록하고 dll은 해당 디렉토리에 복사하면 됨.

이 방법은 실행 시간에 DLL을 로드할 수 있게 해주며, 링크 시간에는 임포트 라이브러리를 통해 심볼을 해결합니다.

3. 프로젝트 설정 조정

Visual Studio 프로젝트 설정에서 다음을 확인하세요:

  1. 추가 종속성: 프로젝트 속성 > 링커 > 입력 > 추가 종속성에 .dll 대신 .lib 파일을 추가하세요.
  2. 모듈 정의 파일: DLL을 만들 때 모듈 정의 파일(.def)을 사용하는 경우, 이 파일이 올바른지 확인하세요.
  3. 라이브러리 디렉토리: 링커가 .lib 파일을 찾을 수 있도록 라이브러리 디렉토리 경로가 올바르게 설정되어 있는지 확인하세요.

4. 전처리기 경고 제거

링커 오류와 함께 전처리기 경고가 발생하는 경우, 다음과 같이 해결할 수 있습니다:

Alt+Enter 누른 후
C/C++ - 전처리기 - 전처리기 정의에서 추가 시켜줘야함

이는 필요한 매크로를 정의하여 컴파일러 경고를 제거합니다.

실제 사례 분석

다음은 실제 프로젝트에서 LNK1107 오류가 발생한 사례입니다:

"C:\code\picotorrent-develop\picotorrent-develop\build-x64\PicoTorrent.sln"(Build 대상)(1) ->
"C:\code\picotorrent-develop\picotorrent-develop\build-x64\WebSocket.vcxproj.metaproj"(기본 대상)(9)->
"C:\code\picotorrent-develop\picotorrent-develop\build-x64\WebSocket.vcxproj"(기본 대상)(10)->

이 사례에서는 WebSocket 프로젝트에서 필요한 헤더 파일이 누락되었습니다:

c:\code\picotorrent-develop\picotorrent-develop\plugins\websocket\src\TorrentEventSink.hpp(10): fatal error C1083: 포함 파일을 열 수 없습니다. 'websocketpp/config/asio_no_tls.hpp': No such file or directory

이 경우 해결책은 필요한 라이브러리(websocketpp)를 다운로드하고 include 경로에 추가하는 것입니다:

https://www.zaphoyd.com/websocketpp

include에 넣어주니 잘 넘어감

복잡한 프로젝트에서의 DLL 관리

대규모 프로젝트에서는 DLL 의존성 관리가 복잡해질 수 있습니다. 이때 유용한 접근법은 다음과 같습니다:

  1. 명확한 프로젝트 구조 유지: 각 DLL과 관련 .lib 파일을 잘 구성된 디렉토리 구조에 유지하세요.
  2. 빌드 순서 관리: 프로젝트 의존성을 명확히 설정하여 올바른 순서로 빌드되도록 하세요.
  3. 빌드 후 이벤트 활용: 빌드 후 이벤트를 사용하여 DLL 파일을 올바른 위치에 자동으로 복사할 수 있습니다: xcopy "$(OutDir)$(TargetName).dll" "$(SolutionDir)bin\" /Y
  4. NuGet 패키지 관리자 활용: 가능하면 서드파티 DLL 의존성을 NuGet을 통해 관리하면 호환성 문제를 줄일 수 있습니다.

심화: 링커의 작동 방식 이해하기

Visual Studio 링커가 어떻게 작동하는지 이해하면 이러한 오류를 더 효과적으로 해결할 수 있습니다:

  1. 링킹 프로세스: 링커는 .obj 파일들을 가져와 실행 파일(.exe) 또는 동적 링크 라이브러리(.dll)로 조합합니다.
  2. 심볼 해결: 각 .obj 파일에는 외부 심볼에 대한 참조가 포함되어 있으며, 링커는 이러한 참조를 해결합니다.
  3. 임포트 라이브러리: .lib 파일은 실제로 DLL에서 내보낸 함수에 대한 스텁(stub)을 포함하고 있으며, 실행 시간에 DLL을 로드하는 데 필요한 정보를 제공합니다.
  4. 정적 라이브러리와 동적 라이브러리의 차이: 정적 라이브러리(.lib)는 링크 시간에 코드가 실행 파일에 직접 포함되는 반면, 동적 라이브러리(.dll)는 실행 시간에 로드됩니다.

결론

LNK1107 오류는 주로 링커에 DLL 파일을 직접 전달할 때 발생하는 문제입니다. 이 오류를 해결하기 위한 핵심은 DLL 자체 대신 해당 DLL의 .obj 파일이나 임포트 라이브러리(.lib)를 사용하는 것입니다.

또한, 프로젝트 설정을 올바르게 구성하고, 의존성 경로를 명확히 하며, DLL 파일을 적절한 위치에 배치하는 것이 중요합니다. 이러한 기법을 통해 Visual Studio에서 발생하는 대부분의 링커 오류를 효과적으로 해결할 수 있습니다.

마지막으로, 링커 오류 메시지를 주의 깊게 읽고 그 의미를 이해하는 것이 문제 해결의 첫 번째 단계임을 기억하세요. 오류 메시지는 종종 문제의 원인과 해결 방향을 명확히 제시합니다.

Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다