#c# #string #pinvoke
#c# #строка #pinvoke
Вопрос:
Я пытаюсь привязать эту функцию C с помощью PInvoke.
bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode);
Вот подпись PInvoke.
[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
public static extern bool GuiTextBox(Rectangle bounds,
string text,
int textSize,
bool freeEdit);
Когда я пытаюсь его использовать, строка не изменяется. Я пытался передать его как ref, но при попытке использовать защищенную память происходит сбой при попытке чтения или записи.
Комментарии:
1.
string
является неизменяемым. Попробуйте создатьStringBuilder
и передать это вместо этого.2. Попробуйте установить кодировку для
DllImport
или настроить пользовательскую сортировку для вашей строки, как здесь learn.microsoft.com/en-us/dotnet/framework/interop /…3.
StringBuilder
вместоString
? будьте изобретательны с кодировкой:CharSet = CharSet.Unicode
илиCharSet = CharSet.Ansi
4. Предоставленной вами информации недостаточно для ответа. Что такое прямоугольник как со стороны C #, так и со стороны C? Что функция C делает с параметрами? Как вызвать метод C #?
5. Не поймите это неправильно, но некоторые исследования привели бы к сотням тем на
StringBuilder
.
Ответ №1:
Я ожидаю, что это должно быть что-то вроде этого:
// private : do not expose inner details;
// we have to manipulate with StringBuilder
[DllImport(nativeLibName,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = "GuiTextBox",
CharSet = CharSet.Unicode)] //TODO: Provide the right encoding here
private static extern bool CoreGuiTextBox(Rectangle bounds,
StringBuilder text, // We allow editing it
int textSize,
bool freeEdit);
// Here (in the public method) we hide some low level details
// memory allocation, string manipulations etc.
public static bool CoreGuiTextBox(Rectangle bounds,
ref string text,
int textSize,
bool freeEdit) {
if (null == text)
return false; // or throw exception; or assign "" to text
StringBuilder sb = new StringBuilder(text);
// If we allow editing we should allocate enough size (Length) within StringBuilder
if (textSize > sb.Length)
sb.Length = textSize;
bool result = CoreGuiTextBox(bounds, sb, sb.Length, freeEdit);
// Back to string (StringBuilder can have been edited)
// You may want to add some logic here; e.g. trim trailing ''
text = sb.ToString();
return resu<
}