[英]DllImport, Char*& and StringBuilder C/C#
我有一個問題,我試着看幾乎所有的海報解決方案,找不到合適的解決方案。
問題很簡單,想在我的托管C#中使用非托管C代碼返回一個字符串。 c函數是:
extern "C" __declspec(dllexport) int process_batch (char *&result);
在C#中我導入了DLL:
[DllImport("mydll.dll")]
public static extern IntPtr process_batch(StringBuilder result);
我跑,但我的StringBuilder中的返回值是一個7-8字符的無意義字符串! (我認為內存地址)
我嘗試在StringBuilder之前添加ref,這次我在StringBuilder中獲得了正確的返回值但是我得到了AccessViolationException:嘗試讀取或寫入受保護的內存。 這通常表明其他內存已損壞。
所以我需要你的幫助來解決這個問題。
還有一件事,我在c中使用malloc將內存分配給char *變量。
謝謝,
如果你真的想這樣做,將參數作為ref IntPtr
傳遞,然后調用Marshal.PtrToStringAnsi或類似的。
[DllImport("mydll.dll")]
public static extern IntPtr process_batch(ref IntPtr result);
請注意,由於您在C中使用malloc
分配字符串,因此.NET程序必須跟蹤返回的指針,以便它可以將其傳遞給您以進行解除分配。 否則你會有內存泄漏。
如果您要傳遞ref StringBuilder
,則無法釋放C程序分配的內存。
另外,正如有人在另一篇文章中評論過的那樣,你需要設置調用約定:
[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)]
我一直在成功使用以下代碼:
[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();
}
我建議通過DllImportAttribute
更具體地聲明導入的方法。 例如,嘗試CharSet = CharSet.Auto
位
我知道這與您的原始問題並不完全相關,因為這會使用Windows API,但它可能仍有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.