StringBuilder Маршаллинг проблема в C # - PullRequest
0 голосов
/ 16 января 2011

Я пытаюсь использовать C ++ dll для редактирования моего объекта StringBuilder в C #.Мой код C ++ выглядит так:

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);
}

После вызова PrintHead я ожидаю увидеть, что значение объекта stringBuilder изменилось с "123456 "to" testIsOkey ", но это не меняет.Я не могу понять, где я могу ошибиться.

Спасибо за вашу помощь.

Ответы [ 2 ]

6 голосов
/ 16 января 2011
void __stdcall PrintHead(char* myString) { 
    myString = "testIsOkey"; 
}

Это неверный код C ++.Он просто меняет указатель, который был передан функции.Это не имеет никаких побочных эффектов.Исправление:

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

Но никогда не пишите такой код взаимодействия, функция 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();
0 голосов
/ 16 января 2011

Не нужно ли помечать ref или каким-либо другим атрибутом, чтобы .NET знал, что сортировка должна выполняться в обоих направлениях?

...