2

I am trying to bind this C function using PInvoke.

bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); 

Here is the PInvoke signature.

[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
public static extern bool GuiTextBox(Rectangle bounds, 
                                     string text, 
                                     int textSize, 
                                     bool freeEdit);

When I try to use it the string does not get modified. I tried passing it as ref but it crashes with attempted to read or write protected memory when I try to use it.

6
  • string is immutable. Try creating a StringBuilder and pass that instead. Commented Mar 13, 2019 at 9:01
  • Try to set charset for DllImport or setup custom marshalling for your string, like here learn.microsoft.com/en-us/dotnet/framework/interop/… Commented Mar 13, 2019 at 9:02
  • StringBuilder instead of String? be creaful with encoding: CharSet = CharSet.Unicode or CharSet = CharSet.Ansi Commented Mar 13, 2019 at 9:03
  • 1
    The information you provide is not sufficient to answer. What is Rectangle both on C# and C side? What is the C function doing with the parameters? How do you call the C# method? Commented Mar 13, 2019 at 9:10
  • Don't take this the wrong way, but a some research would have led to hundreds of topics on StringBuilder. Commented Mar 13, 2019 at 9:36

1 Answer 1

2

I expect it should be something like this:

// 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 '\0'  
  text = sb.ToString();

  return result;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.