DllImport, Char*& and StringBuilder C/C#

孤街浪徒 提交于 2019-12-13 15:05:41

问题


I have a problem, I tried to look at almost all the poster solutions, unsuccessful to find a suitable one.

The question is easy, Want to have a return string from unmanaged C code in my managed C#. The c function is:

extern "C" __declspec(dllexport) int process_batch (char *&result);

and in C# I imported the DLL:

[DllImport("mydll.dll")]
public static extern IntPtr process_batch(StringBuilder result);

I run, but the return value in my StringBuilder is a 7-8 character string of non-sense! (I think the memory address)

I tried adding ref before the StringBuilder, this time I get the correct return value in StringBuilder but I get AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

So I need your help to fix this.

Just one more thing, I use malloc in c for allocating the memory to the char* variable.

Thanks,


回答1:


If you really want to do that, pass the parameter as a ref IntPtr, then call Marshal.PtrToStringAnsi, or similar.

[DllImport("mydll.dll")]
public static extern IntPtr process_batch(ref IntPtr result);

Note that, since you're allocating the string with malloc in C, the .NET program will have to keep track of the returned pointer so that it can pass it back to you to be deallocated. Otherwise you'll have a memory leak.

If you were to pass a ref StringBuilder, you wouldn't be able to deallocate the memory that was allocated by the C program.

Also, as somebody commented in another post, you need to set the calling convention:

[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)]



回答2:


I've been using the following code successfully:

[DllImport("user32.dll", EntryPoint = "GetClassName", ExactSpelling = false,
            CharSet = CharSet.Auto, SetLastError = true)]
private static extern int _GetClassName(IntPtr hwnd, StringBuilder lpClassName,
            int nMaxCount);

public static string GetClassName(IntPtr hWnd)
{
   StringBuilder title = new StringBuilder(MAXTITLE);
   int titleLength = _GetClassName(hWnd, title, title.Capacity + 1);
   title.Length = titleLength;

   return title.ToString();
}

I'd advise for a more specific declaration of the imported method via the DllImportAttribute. Try the CharSet = CharSet.Auto bit for instance

I know that this is not exactly related to your original problem as this makes use of the Windows API, but maybe it is of help nonetheless.



来源:https://stackoverflow.com/questions/6063428/dllimport-char-and-stringbuilder-c-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!