2010-12-15 6 views
2

C# 응용 프로그램은 런타임에 C++ DLL에서 함수를 호출하고 예외를 throw합니다. 생성 된 오류 코드는 262입니다. 불행히도 Microsoft documentation은이 코드에 약간 부족합니다.런타임에 C++ DLL에서 예외가 발생합니다.

이상하게도 DLL (별도 프로젝트)과 동일한 Visual Studio 솔루션의 일부인 C++ 테스트 응용 프로그램에서 DLL을 실행하면 예외가 발생하지 않습니다. C# 응용 프로그램은 완전히 별도의 솔루션입니다. COM을 초기화하고 응용 프로그램에서 WMI를 쿼리하는 데 사용하는 첫 번째 단계는 CoInitializeEx을 호출하여 오류 코드를 반환합니다.

유일한 다른 점은 관련이있는 것 같다 내가 종속성 워커와 DLL을 열 때 나는 이러한 오류 및 경고를 얻을 :

Error: At least one required implicit or forwarded dependency was not found.
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.

나에게 발생하는 유일한 방법은 그 암시 적 요구 "없거나 의존성 "은 CoInitializeEx을 만들 필요가있다. 종속성 워커에 따르면,이 모듈을 찾을 수 없습니다 :

  • MSVCR90D.DLL
  • IESHIMS.DLL
  • WER.DLL

어떤 생각이나 제안이 평가됩니다. 감사.

+0

운이 좋다. 마지막으로 필자는 링커 문제 (Microsoft 세계에서 완전히 엉망입니다 ...)가 발생해도 코드가 추락하지 않고 문제를 파악하는 데 몇 시간이 걸렸습니다. DLL을 호출하는 프로그램과 DLL이 연결된 런타임 라이브러리 *를 연결해야합니다. –

답변

1

특정 시나리오에서 별도의 스레드가 가장 좋은 방법 일 수 있습니다.

DLL에서 스레드를 만드는 것은 DLL이 프로세스의 수명을 소유하지 않기 때문에 지저분한 일입니다. 소유자는 EXE입니다.

그러나 ... 동기식으로 실행하면 (스레드 생성, 초기화, 스레드 대기 완료 후 계속), 일반적으로 안전합니다. 스레드를 캐시 할 수 있으므로 매번 생성하고 CoInitialize() 할 필요가 없지만 백그라운드에서 작동하고 호출자에게 돌아 가지 않도록하십시오. 다시 말하면, 미묘한 생애 문제가 발생합니다.

+0

또한 @ Hans의 회신에서 문제 진단에 대한 중요한 정보를 확인하십시오. –

0

릴리스 또는 디버그 모드로 모든 것을 컴파일했는지 확인하십시오.

I.E의 http 기반 기능을 사용하고 있습니까? 왜 당신이 ieshims.dll에 의존하는지 궁금합니다.

1

Visual Studio 2008 C++가 설치되어 있지 않은 것으로 가정합니다. MSVCR90D.dll이 DLL은 디버그 DLL로 컴파일 된 DLL을로드하려고 시도하는 디버그 전용 DLL입니다.

이 다른 사람으로 ...이 스레드를 참조하십시오 Dependency Walker reports IESHIMS.DLL and WER.DLL missing?

4

, 당신은 아마 점점 실제 오류가 0x80010106입니다, 마지막 단어가 오류 코드가 RPC_E_CHANGED_MODE입니다 (262) 당신의 오류 처리가 정결하지 않습니다, "스레드 모드를 설정 한 후에는 변경할 수 없습니다." 이전에 CoInitialize/Ex가 호출되어 STA에서 MTA로 또는 다른 방법으로 변경하려고 시도 할 때 CoInitialize/Ex가 반환하는 것은 무엇입니까?

스레드의 아파트 상태가 CoInitializeEx()에 대한 첫 번째 호출에서 잠겨 있습니다. 첫 번째 전화가 발생한 곳을 찾아야합니다. 이는 예를 들어 관리되는 스레드에 대한 CLR로 수행 할 수 있습니다. 스레드의 아파트 상태는 시작 스레드의 Main() 메서드에서 [STAThread] 또는 [MTAThread]에 의해 결정됩니다. 또는 직접 만든 관리되는 스레드에 대한 Thread.SetApartmentState(). 스레드 풀 스레드는 항상 MTA이며 변경할 수 없습니다.

스레드의 아파트 상태를 변경하면 많은 부작용이 발생할 수 있습니다.

+0

한스, 네가 뭔가있는 것 같아. 이 C# 응용 프로그램에는 제어 할 수없는 많은 코드가 있습니다. 그것은 몇 가지 새로운 하드웨어를 지원하기 위해 업데이 트하는 현장 응용 프로그램입니다. C++ DLL에서'CoInitializeEx'가 호출되어야 하는지를 결정적으로 확인하는 방법이 있습니까? 아니면 프로그래밍 방식으로 스레드의 아파트 상태를 확인할 수있는 방법이 있습니까? 감사. –

+3

C++ DLL이 CoInitializeEx()를 호출하는 것은 거의 항상 잘못된 것입니다. 그것이 스레드 자체를 생성하지 않는 한. –

+0

그래,하지만 불행히도, 나는 그것에 의지 할 수 없다. 'CoInitializeEx'에 조건부 호출을하기 전에'CO_E_NOTINITIALIZED'에 대한'CoGetApartmentType'의 반환 값을 평가한다면 어떨까요? –

0

오류 WIN32 = 262는 HRESULT = -2147024634 (0x80070106)입니다. 이것은 다른 것입니다. CoInitializeEx은 모든 스레드에 대해 한 번만 호출되어야하지만 두 번 이상 호출되는 경우 CoInitializeEx마다 하나씩 CoUninitialize이 있어야합니다.

+1

-1을 치면 자신을 설명해야합니다. –

관련 문제