簡體   English   中英

DllImport,Char *&和StringBuilder C / C#

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM