DllImport、Char*&和 StringBuilder C/C#

发布于 2024-11-08 05:22:33 字数 602 浏览 3 评论 0原文

我有一个问题,我尝试查看几乎所有的海报解决方案,但未能找到合适的解决方案。

问题很简单,想要在我的托管 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* 变量。

谢谢,

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,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

赴月观长安 2024-11-15 05:22:38

如果您确实想这样做,请将参数作为 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)]

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)]
迷爱 2024-11-15 05:22:38

我已经成功地使用了以下代码:

[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,但也许它仍然有帮助。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文