2011-01-16 6 views
0

C#에서 d ++를 사용하여 StringBuilder 개체를 편집하려고합니다. 내 C++ 코드는 다음과 같습니다C#의 StringBuilder 마샬링 문제

extern "C" __declspec(dllexport) void __stdcall PrintHead(char* myString) 
{ 
    myString = "testIsOkey"; 
} 

내 C# 코드는 다음과 같습니다

프린트 헤드가 호출 된 후
[DllImport("StringEdit.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = false)] 

public static extern void PrintHead([MarshalAs(UnmanagedType.LPStr)] StringBuilder stringBuilder); 

private void button1_Click(object sender, EventArgs e) 
{ 
    StringBuilder stringBuilder = new StringBuilder("123456"); 
    PrintHead(stringBuilder); 
} 

, 난에 "123456"에서의 StringBuilder 개체의 값이 변경되는 것을 볼 것으로 예상하고있다 " testIsOkey "하지만 변경되지 않습니다. 나는 어디에서 실수를하는지 알 수 없다.

도움 주셔서 감사합니다.

답변

-1

ref 또는 다른 속성으로 표시 할 필요가 없으므로 .NET에서 마샬링이 양방향으로 수행되어야한다는 것을 알 수 있습니까?

6
void __stdcall PrintHead(char* myString) { 
    myString = "testIsOkey"; 
} 

그건 잘못된 C++ 코드입니다. 은 함수에 전달 된 포인터를으로 변경합니다. 이것은 부작용이 전혀 없습니다. 수정 :

void __stdcall PrintHead(char* myString) { 
    strcpy(myString, "testIsOkey"); 
} 

그러나 이와 같은 interop 코드는 작성하지 않아도 C++ 함수는 이러한 방식으로 가비지 수집 힙을 쉽게 파괴 할 수 있습니다. 정확히 어떤 일이 당신의 코드에서 일어나는지, StringBuilder의 용량으로는 충분하지 않습니다. 전달 된 버퍼의 크기를 제공하는 추가 인수를 추가해야합니다. 수정 :

void __stdcall PrintHead(char* myString, size_t bufferSize) { 
    strcpy_s(myString, bufferSize, "testIsOkey"); 
} 

이 같은 여분의 인수에 스트링 빌더의 용량을 전달합니다

var buffer = new StringBuilder(666); 
PrintHead(buffer, buffer.Capacity); 
var result = buffer.ToString(); 
+3

프린트 헤드에 대한 호출이 실제로해야한다 '프린트 헤드 (버퍼, buffer.Capacity + 1);' 마샬 러에 의해 추가 된 널 바이트를 설명합니다. 자세한 내용은 http://msdn.microsoft.com/en-us/library/s9ts558h.aspx의 하단 섹션을 참조하십시오. – MrSlippers