我有一个问题,我试着看了几乎所有的海报解决方案,都没能找到一个合适的。
问题很简单,我希望在我的托管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*变量。
谢谢,
发布于 2011-05-20 03:22:46
如果您真的想这样做,请将参数作为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)]发布于 2011-05-20 02:57:53
我已经成功地使用了以下代码:
[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,但它可能会有所帮助。
https://stackoverflow.com/questions/6063428
复制相似问题