소스 코드를 사용할 수없는 제 3의 독점적 인 DLL을 사용하고 있습니다. 그러나 SWIG 1.3.39를 사용하여 자동 생성 된 것으로 보이는 래퍼 코드는 나에게 제공됩니다. 래퍼 코드는 (DLL을 설명하는 일부 헤더를 사용하여) DLL로 컴파일하고 C++ 래퍼 DLL에 PInvoke 호출을 수행하는 C# 프로젝트를 컴파일하는 C++ 파일로 구성됩니다.64 비트 Windows에서 C++에서 C#으로 문자열을 반환 할 때 AccessViolationException을 방지하려면 어떻게해야합니까?
필자는 공급 업체의 설명서를 해석 할 때 대상 플랫폼에 따라 x86 또는 x64로 솔루션의 모든 것을 컴파일했습니다. 공급 업체는 독점 DLL의 32 비트 및 64 비트 버전을 모두 제공하며 주어진 빌드에 대해 올바른 버전을 사용하도록했습니다. 내 컴퓨터는 32 비트입니다. 릴리스 또는 디버그 빌드에서 내 시스템에서 내 응용 프로그램의 x86 버전을 테스트하면 정상적으로 작동하는 것 같습니다. 그러나 64 비트에서 응용 프로그램은 디버그 모드에서 작동하지만 릴리스 모드에서는 System.AccessViolationException으로 실패합니다.
나는 블로그 게시물을 야기한 this question and answer뿐만 아니라 디버그 대 릴리스 문제를 잘 설명하는 것으로 보이는 this nice blog entry을 읽었습니다. 그러나이 경우 문제를 해결하는 방법을 잘 모르겠습니다.
AccessViolationException은 실제 길이의 문자열이 C++ 래퍼에서 반환되거나 반환되도록 처음 시도 된 것으로 보입니다.
// In one file of the C# wrapper:
public string GetKey()
{
// swigCPtr is a HandleRef to an object already created
string ret = csWrapperPINVOKE.mdMUHybrid_GetKey(swigCPtr);
return ret;
}
// In the csWrapperPINVOKE class in another file in the C# wrapper:
[DllImport("csWrapper.dll", EntryPoint="CSharp_mdMUHybrid_GetKey")]
public static extern StringBuilder mdMUHybrid_GetKey(HandleRef jarg1);
그리고 C++ 래퍼에서 번잡 한 C++ 코드 :
SWIGEXPORT char * SWIGSTDCALL CSharp_mdMUHybrid_GetKey(void * jarg1) {
char * jresult ;
mdMUHybrid *arg1 = (mdMUHybrid *) 0 ;
char *result = 0 ;
arg1 = (mdMUHybrid *)jarg1;
result = (char *)(arg1)->GetKey();
jresult = SWIG_csharp_string_callback((const char *)result);
return jresult;
}
SWIGEXPORT
가 이미 __declspec(dllexport)
로 정의했다
SWIG_csharp_string_callback
을 발견 :
/* Callback for returning strings to C# without leaking memory */
typedef char * (SWIGSTDCALL* SWIG_CSharpStringHelperCallback)(const char *);
static SWIG_CSharpStringHelperCallback SWIG_csharp_string_callback = NULL;
합니다 (C# 1 래퍼) 대리인 설정되고 하였다
static string CreateString(string cString) {
return cString;
}
I과 같은 구조를 사용하는 코드 장난 시도 Marshal.PtrToStringAut
을 사용할 수 없습니다. 이 문제를 어떻게 해결합니까?
나는 똑같은 문제에 부딪 쳤고이 게시물은 실제로 그것을 고쳤다. 그러나, 나는 어떻게하면 불쾌한 코드를 발견했는지 알고 싶다. 릴리스 모드에서 프로젝트를 실행할 때 예외가 발생하지 않았기 때문입니다. "액세스 위반"은 내가 폴더를 해제하고 거기에서 직접 exe를 실행할 때 그림으로 나타납니다! – Simsons
@Subhen 시간이 지났으므로 고용주가 변경되어 더 이상이 코드에 액세스 할 수 없습니다. 기억 나면 Windows Server 인스턴스에서이 작업을 실행하고 원격 디버거를 어떻게 든 사용할 수있었습니다. 나는 그것에 착각 할 수는 있었지만, 이것이 깨고있는 곳을 찾기 위해 하루 이틀이 걸렸습니다. 로깅은 물론 예외를 얻을 때 코드에있는 위치를 정확하게 기록 할 수 있다면 도움이 될 수 있습니다. – Andrew