문제

이 기능은 Visual C ++ DLL에 있습니다

char * __stdcall GetMessage(int id) {
char buffer[250];
.
.
.
strcpy(buffer, entry); // entry is a char * that has allocated 250 chars
return (char *)buffer;
}

다음 코드로 C# 에서이 기능을 가져 오려고합니다.

[DllImport("mydll.dll", CharSet=CharSet.Ansi)]
public static extern string GetMessage(int id);

나는 이것을 메시지 상자에 제시하려고 노력하고 있습니다. 그것은 항상 문자열 끝에 이상한 기호가 있습니다. 이 문제를 극복하는 방법이 있습니까?

도움이 되었습니까?

해결책

C ++ 코드가 유효하지 않다는 사실을 다시 강조하겠습니다. 함수가 반환 될 때 더 이상 유효하지 않은 스택 프레임의 로컬 변수에 대한 포인터를 반환합니다. 그것이 작동한다는 것은 단지 사고 일뿐입니다. 다른 기능을 호출하자마자 스택 공간이 재사용되어 버퍼 컨텐츠가 손상됩니다. 이는 C#에서이 코드를 호출 할 때 보장됩니다. P/Invoke Marshaller 구현은 스택 프레임을 덮어 쓰고 버퍼를 손상시킵니다.

설상가상으로, P/호출 Marshaller는 버퍼를 제거하려고합니다. 버퍼가 CotaskMemalloc ()에 의해 할당되었다고 가정하고 CotaskMemfree () 호출하여 버퍼를 해제한다고 가정합니다. 그것은 Windows XP에서 조용히 실패하지만 이전에는 Vista 이상에서 프로그램을 충돌시킵니다.

이 문제에 대한 하나의 솔루션 인 CotaskMemalloc ()을 사용하여 로컬 변수를 사용하는 대신 버퍼를 할당하십시오. 만능 더 나은 솔루션은 함수의 발신자가 버퍼를 통과하여 문자열로 채워 지도록하는 것입니다. 이렇게하면 발신자가 버퍼를 할당하고 필요에 따라 청소하는 방법을 결정할 수 있습니다. 함수 서명은 다음과 같아야합니다.

extern "C" __declspec(dllexport)
void __stdcall GetMessage(int id, char* buffer, size_t bufferSize);

strcpy_s ()를 사용하여 버퍼를 안전하게 채우고 버퍼 오버플로를 피하십시오. 그런 다음 해당 C# 선언은 다음과 같습니다.

[DllImport("mydll.dll")]
private static extern void GetMessage(int id, StringBuilder buffer, int bufferSize);

다음과 같이 호출됩니다.

var sb = new StringBuilder(250);
GetMessage(id, sb, sb.Capacity);
string retval = sb.ToString();

다른 팁

DLL에서 GetMessage 함수 내의 스택에있는 char 배열 IE 버퍼를 반환하고 있으며, 리턴이 실행되면 버퍼가 스택에서 튀어 나와 스택에 로컬이기 때문에 데이터가 엉망이됩니다. 당신이보고있는 이상한 캐릭터. 이 문제를 해결할 수있는 두 가지 방법이 있습니다. 버퍼 변수 선언을 포인터로 변경하고 반환하기 전에 Malloc을 변경하거나 정적으로 선언합니다.

char *buffer;
if (!(buffer = (char *)malloc((250 * sizeof(char)) + 1)){
   // Handle the out of memory condition
}
// Now the buffer has 250 + 1 for null terminating character.

또는

static char buffer[250];

또한 입력 포인터 변수를 명확히 할 수 있습니까?

이것이 도움이되기를 바랍니다.

리턴 유형에 StringBuilder를 사용해보고 charset 속성을 남기십시오.

[DllImport("mydll.dll")]
public static extern StringBuilder GetMessage(int id);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top