0

Visual Studio 디버거에 EEAddIn으로 사용되는 관리되는 C++ DLL이 있습니다. 내 dll은 관리되지 않는 유형을 수락하고 반환하는 하나의 함수를 내 보냅니다.Visual Studio 프로세스에서 호출 할 때 관리되는 C++ dll 함수가 반환시 액세스 위반을 throw합니다.

내 DLL의 목적은 비주얼 스튜디오 디버거에서 변수를 처리하기 이전에 표시하는 임의의 방식으로 포맷 할
extern "C" 
{ 
#pragma unmanaged 
    __declspec(dllexport) HRESULT CvMatViewer(DWORD dwAddress, DEBUGHELPER *pHelper, 
    int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved) 
    { 
    strcpy_s(pResult, max, "Value is processed"); 
    return S_OK; 
    } 
} 

입니다 : DLL에있는 함수의 선언은 다음과 같이 (DEBUGHELPER은 일반 구조는)입니다 Watch Window (EEAddIn은 꽤 멋지다).

두 개의 Visual Studios가 시작되었습니다. 하나는 내 관리 대상 DLL이고 다른 하나는 기본 디버깅 된 exe입니다. 내 exe를 실행하고 중단 점을 설정하는 Visual Studio의 프로세스에 내 DLL을 연결할 수 있습니다. 조사 식 창에서 변수를 추가하면 내 중단 점이 발생합니다. 모든 매개 변수가 올바르게 전달되고 함수가 return 문에 도달 할 때까지 제대로 작동하는지 확인할 수 있습니다.

그 후 나는 Unhandled exception at 0x51ea9de4 in devenv.exe: 0xC0000005: Access violation reading location 0x00000000입니다.

관리되지 않는 dll에서도 동일한 방식으로 작동합니다. 문제가 숨겨진 부분을 누구나 추측 할 수 있습니까?

두 비주얼 스튜디오 모두 2010 버전입니다.

예, 관리되지 않는 dll을 사용하여이 호출을 수락 한 다음 다른 관리되는 dll로 제어를 전달할 수 있지만 Occam의 면도기 원칙을 통해 알 수 없음을 알립니다.

업데이트 : pResult는 NULL이 아니며, 예외 내가 strcpy_s 밖으로 코멘트 경우에도 발생합니다.

+0

VS의 단일 인스턴스를 사용하여 동일하게 실행 해 보았습니까? 내 말은, 단지 하나의 VS에서 EXE를 디버깅하기 시작하고 거기에서부터 AV가이 경우에 재생산됩니까? – unkulunkulu

+0

@unkulunkulu이 경우 VS는 방금 변수의 내용을 평가하기 위해 DLL이 호출 된 순간 충돌합니다. 내가 충돌 후 그것을 디버그하고 동일한 AV를 볼 수 있습니다. – Mikhail

답변

1

이 함수에 stdcall 호출 규칙을 명시 적으로 설정해야하는 것처럼 보입니다. 그러면 도움이 될 것입니다.

__declspec(dllexport) HRESULT __stdcall CvMatViewer(DWORD dwAddress, DEBUGHELPER *pHelper, 
    int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved); 
+0

이 경우 VS에서 함수가 호출되지 않습니다. 그리고 모든 매개 변수가 기본 '__cdecl' 규칙 (즉,'nBase'의 값은 10이고'max'의 값은 2048)으로 올바르게 보였으므로 호출 규칙이 문제라고 생각하지 않습니다. – Mikhail

+0

@Mikhail에서는 어떤 규칙을 사용하든 매개 변수가 올바르게 전달되지만 스택을 정리하는 사람 만 다릅니다. – unkulunkulu

+0

@Mikhail, 함수가 지금 호출되지 않는 이유는 아마도'__stdcall'을 가진 변경된 이름 변환 체계 일 것입니다 (이것은'extern C'만으로 발생합니다), 당신은 unmangled 이름으로 함수를 내보내기 위해 모듈 정의 파일을 작성해야합니다 . 세상에서 잘못된 전화 협약이 어떻게 문제가되지 않을 수 있습니까? – unkulunkulu

0

pResult가 데이터를 복사하기 전에 실제로 null 포인터가 아닌지 확인합니다. 함수의 크기를 고려할 때 문제가 발생할 가능성이 큽니다.

+0

아니요, NULL이 아니며이 strcpy_s를 주석 처리하더라도 예외가 발생합니다. – Mikhail

관련 문제