c# to c ++/cli to c dll system.io.filenotfoundException
-
22-07-2019 - |
문제
나는 얻는다 System.IO.FileNotFoundException: The specified module could not be found
C ++/CLI 어셈블리를 호출하는 C# 코드를 실행할 때 순수한 C DLL이라고합니다. 순수한 C DLL 함수를 호출하는 객체가 인스턴스화되는 즉시 발생합니다.
Backingstore는 순수한 C입니다. CPPDEMOViewModel은 C ++/CLI 호출 BackingStore입니다. BackingStore에 대한 참조가 있습니다.
가능한 가장 간단한 경우를 시도했습니다. CPPDEMOViewModel에 정의 된 객체를 만들려고 시도하는 새로운 C# 단위 테스트 프로젝트를 추가합니다. C# 프로젝트에서 cppdemoviewModel에 참조를 추가했습니다.
C ++/CLI 테스트 프로젝트는 CPPDEMOViewModel에 추가 된 참조만으로 잘 작동하므로 언어간에가는 것입니다.
.NET 3.5 SP1과 함께 Visual Studio 2008 SP1을 사용하고 있습니다. Vista X64를 기반으로하고 있지만 내 플랫폼 대상이 X86으로 설정되어 있는지주의를 기울였습니다.
이것은 내가 실종 된 바보 같은 느낌이 들지만 개인적으로 그것을 해결하려고 시간을 낭비하는 것이 훨씬 어리석은 일입니다. 그래서 나는 여기에 당황하고 있습니다!
이것은 C ++/CLI로 구현 된 뷰 모델을 사용하여 DLL에 보관하는 막대한 양의 레거시 C 코드를 포팅하는 프로젝트 테스트입니다.
편집하다디렉토리를 확인한 후 BackingStore.dll이 복사되지 않았 음을 확인할 수 있습니다.
일반적인 다중 프로젝트 솔루션으로 생성 된 표준 고유 프로젝트 폴더가 있습니다.
WPFViewModelInCPP BackingStore CPPViewModel CPPViewModelTestInCS bin Debug Debug
상위 레벨 디버그는 C 및 C ++/CLI 프로젝트에서 사용하는 일반적인 폴더 인 것으로 보입니다.
wpviewmodelincpp debug backingstore.dll, cppdemoviewmodel.dll, cppviewmodeltest.dll 및 관련 .ilk 및 .pdb 파일을 포함합니다.
wpfviewmodelincpp cppviewmodeltestincs bin debug는 cppdemoviewModel 및 cppviewModelTestincs .dll 및 .pdb 파일을 포함합니다. ~ 아니다 백링 스토어. 그러나 BackingStore를 해당 디렉토리에 수동으로 복사합니다 오류를 수정하지 않았습니다.
cppdemoviewmodel에는 속성이 있습니다 로컬 복사 내가 참조 할 때 DLL을 복사 할 책임이 있다고 가정 한 세트. C# 프로젝트에서 순수한 C DLL에 참조를 추가 할 수 없습니다. 후원 저장소에 대한 참조를 추가 할 수 없습니다.
한두 가지 문제가 있는지 확실하지 않습니다.
새로운 .NET 모델이 필요하지 않기를 희망하지만 구식 복사 빌드 단계를 사용하여 Backingstore.dll을 특정 C# 프로젝트 디렉토리에 복사 할 수 있습니다.
종속성 워커는 누락 된 파일이 gpsvc.dll이라고 말하고 있습니다. 제안되었습니다 보안 설정 문제를 나타냅니다. 나는 이것이 붉은 청어라고 생각합니다.
edit2Backingstore.dll의 수동 사본이 실행 파일에 인접 해있어 GUI는 이제 정상적으로 작동합니다. C# 테스트 프로젝트에는 여전히 테스트 프로젝트의 런타임 환경 때문이라고 생각하는 문제가 있지만 지금은 그없이 살 수 있습니다.
해결책 2
출력 설정 변경을 제외하고 GUI에 대한 답은 사전 건축 단계를 추가하는 것입니다.
copy $(ProjectDir)..\Debug\BackingStore.* $(TargetDir)
테스트 프로젝트에 대한 답은 누락 된 DLL을 TestRunconFig의 배포 탭에 추가하는 것입니다. 기본값을 직접 편집하여 그렇게 할 수 있습니다. LocalTestrun.testrunconfig (솔루션 항목 아래에 솔루션에 나타납니다) 솔루션을 마우스 오른쪽 버튼으로 클릭하고 새로운 테스트 실행 구성을 추가 한 다음 기본 테스트 메뉴 아래에 나타납니다.
답변 해주셔서 감사합니다 이렇게 질문 테스트 구성에 대한 답변으로 이끌었습니다.
다른 팁
이런 일이 발생하는 이유는 CRT가 초기화 될 기회가 있기 전에 관리 코드에서 DLLMAIN을로드하기 때문입니다. 관리 코드가 없거나 실행됩니다. 곧장 또는 비면적으로 dllmain 알림의 효과에서. (참조 : Expert C ++/CLI : Visual C ++ 프로그래머 용 .NET, 11 장 ++).
또는 기본 EntryPoint가 정의 된 wahtsoever는 없지만 MSVCRT에 연결되어 있습니다. CLR은 /clr로 자동으로 초기화되며,이 세부 사항은 많은 혼란을 유발하며 고려해야합니다. 혼합 모드 DLL 지연 하중 CLR은 수업에서 모든 관리 된 진입 점 vtables를 핫 패치를 사용하는 것을 통한 CLR입니다.
이 주제를 둘러싼 다수의 클래스 초기화 문제는 로더 잠금 및 지연 CLR이 때때로 약간 트릭 키입니다. Global의 정적을 선언하고 #Pragma Managed /Manuged를 사용하지 말고 /CLR Per File으로 코드를 격리하십시오.
관리 된 코드에서 코드를 격리 할 수없고 문제가있는 경우 (이 단계 중 일부를 취한 후) CLR을 직접 호스팅하고 도메인 관리자를 만들기위한 노력을 살펴볼 수도 있습니다. 런타임 이벤트 및 부트 스트랩의 완전한 "내부 루프".
이것이 정확히 그 이유입니다. 검색 경로 또는 초기화와 함께 할 일이 없습니다. 불행히도 Fusion Log Viewer는 그다지 도움이되지 않습니다 (이는 의존성 워커가 아닌 .NET CLR 어셈블리 바인딩 문제를 찾을 수있는 일반적인 장소입니다).
정적으로 연결하는 것은 이것에 대해서도 아무것도 없습니다. 당신은 할 수 있습니다 아니다 혼합 모드 인 C ++/CLI 애플리케이션을 정적으로 연결하십시오.
- dllmain 기능을 파일 자체로 배치하십시오.
- 이 파일이 있는지 확인하십시오 아니다 가지다 /clr 빌드 옵션에 설정 (파일 빌드 옵션)
- /md 또는 /mdd와 연결하고 연결하는 모든 종속성이 동일한 CRT를 사용하는지 확인하십시오.
- /defaultlib에 대한 링커 설정을 평가하고 /포함 된 참조 문제를 식별하려면 코드에서 프로토 타입을 선언하고 기본 라이브러리 링크 해상도를 재정의하기 위해 사용 /포함시킬 수 있습니다.
행운을 빕니다. 또한 그 책을 확인하십시오.
이것은 흥미로운 딜레마입니다. C#에서 전화를 한 후 C ++/CLI에서 Native .dlls를로드하는 데 문제가 들어 본 적이 없습니다. 문제가 그와 마찬가지로 가정 할 수 있습니다 @Daniel l 제안 된 것, 그리고 당신의 .dll은 단순히 어셈블리 로더가 찾을 수있는 경로에 있지 않다고 제안했다.
Daniel의 제안이 해결되지 않으면 기본 C 코드를 C ++/CLI 프로그램에 정적으로 연결하는 것이 좋습니다. .dll이 C ++/Cli .dll에 완전히 흡수되므로 문제가 해결 될 것입니다.
대상 시스템에 올바른 MS Visual C 런타임이 있고 디버그 런타임으로 실수로 C DLL을 구축하지 않도록하십시오.
64 비트 비스타로 전환하는 것도 같은 문제가있었습니다. 우리의 응용 프로그램은 응용 프로그램의 대상 빌드를 혼란스럽게하는 Win32 DLL을 호출했습니다. 그것을 해결하기 위해 우리는 다음을 수행했습니다.
- 프로젝트 속성으로 이동하십시오.
- 빌드 탭을 선택하십시오.
- '플랫폼 대상 :'옵션 x86;
- 응용 프로그램을 재건하십시오.
응용 프로그램을 다시 연결하면 작동했습니다.