현재 C++ DLL과 통신하는 일부 C# 코드를 작성하고 있습니다. 이것은 내가 - 또는 내 회사의 다른 누군가 - 어떤 경험이있는 영역이 아닙니다. 가장 적은 것을 말하면서 눈을 뜨게되었습니다.비 관리 C# 코드의 액세스 위반 소스 추적
많은 독서, 시행 착오 및 좌절감을 겪은 후, 나는 대부분의 꼬임을 철저히 제거하고 대부분 기능을 발휘하게되었습니다. 그러나 때로는 여전히 내게 이것을 던졌습니다 ...
System.AccessViolationException : 보호 된 메모리를 읽거나 쓰려고했습니다. 이것은 종종 다른 메모리가 손상되었다는 표시입니다.
.. 그리고 나서 죽는다. 이 오류는 병렬 스레드에서 호출을 실행할 때만 나타납니다. 이 dll은 스레드로부터 안전해야하고 올바르게 처리되어야한다고 믿을만한 충분한 이유가 있습니다.
이 오류의 원인은 항상 같은 함수를 호출입니다: 나는이 함수를 정의하는 라이브러리의 헤더 파일이
[DllImport(DLL, SetLastError = true, CharSet = CharSet.Ansi)]
public static extern int QABatchWV_Close(IntPtr vi1);
: 어떤에서
__declspec(dllimport) int __stdcall QABatchWV_Close(int);
를 I 내가 처분 할 수있는 SafeHandle 및 MarshalAs와 같은 추가 도구가 있음을 이해하십시오. 솔직히, 나는이 상황에서 어떻게 그들을 가장 잘 배치 할 수 있는지 확신 할 수 없다.
이 오류는 표시하는 데 몇 시간의 시간이 걸리는 경향이 있으므로 조정과 희망은 여기서 생산적인 접근 방식이 될 수 없습니다. 누구든지 내가 C++ 함수를 호출 할 때 잘못된 일을 할 수 있다고 지적 할 수 있습니까?
반환 값에서와 같이 매개 변수를'int' 대신'IntPtr'로 사용하기로 결정한 이유가 있습니까? – nvoigt
@novigt 실험적으로 행동하도록 유도합니다. 나는 양쪽 끝에서 int로, 양쪽 끝에서 IntPtr, 그리고 그림과 같이 각각 하나씩 시도했다. 나는 이것에 관해 나의 깊이에서 빠져 나가고, 단지 필사적으로 물건을 시험해 보는 것을 기뻐한다. –
C++의 라이브러리를 컴파일 할 때'int'가 어떤 크기인지 알아야합니다. 그렇다면 C#에서 올바른 것을 고를 필요가 있습니다. 'IntPtr'은 코드를 어디서 실행하는지에 따라 32 비트 또는 64 비트입니다. C++ 라이브러리는 런타임시 C#이 할 수 있음을 결정할 수 없으며 컴파일시 수정 될 것입니다. – nvoigt