Строка Pinvoke на C #

#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<
}