PInvoke的为C函数返回的char * [英] PInvoke for C function that returns char *

查看:349
本文介绍了PInvoke的为C函数返回的char *的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着写一些C#code调用从非托管DLL的方法。原型在DLL中的函数是:

I'm trying to write some C# code that calls a method from an unmanaged DLL. The prototype for the function in the dll is:

extern "C" __declspec(dllexport) char *foo(void);

在C#中,我第一次使用:

In C#, I first used:

[DllImport(_dllLocation)]
public static extern string foo();

这似乎在表面上工作,但在运行时我得到的内存损坏错误。我想我指着内存恰好是正确的,但已被释放。

It seems to work on the surface, but I'm getting memory corruption errors during runtime. I think I'm pointing to memory that happens to be correct, but has already been freed.

我试着使用的PInvoke code根工具称为P / Invoke的互操作助手。它给我的输出:

I tried using a PInvoke code gen utility called "P/Invoke Interop Assistant". It gave me the output:

[System.Runtime.InteropServices.DLLImportAttribute(_dllLocation, EntryPoint = "foo")]
public static extern System.IntPtr foo();

这是正确的?如果是这样,我怎么这样的IntPtr转换为字符串在C#中?

Is this correct? If so, how do I convert this IntPtr to a string in C#?

推荐答案

您必须返回这是一个IntPtr。返回从函数的PInvoke以System.String类型需要非常谨慎。在CLR必须从本地重新presentation传输存储到托管之一。这是一个容易和predictable操作。

You must return this as an IntPtr. Returning a System.String type from a PInvoke function requires great care. The CLR must transfer the memory from the native representation into the managed one. This is an easy and predictable operation.

问题虽然带有如何处理是从foo()返回的本机内存做。 CLR的假设有关PInvoke的函数直接返回字符串类型的以下两个项目

The problem though comes with what to do with the native memory that was returned from foo(). The CLR assumes the following two items about a PInvoke function which directly returns the string type


  1. 本机内存需要释放

  2. 本机内存与分配CoTaskMemAlloc

因此​​,它将元帅字符串,然后调用CoTaskMemFree在本机内存斑点。除非你实际上CoTaskMemAlloc分配这个内存,这将充其量导致应用程序崩溃。

Therefore it will marshal the string and then call CoTaskMemFree on the native memory blob. Unless you actually allocated this memory with CoTaskMemAlloc this will at best cause a crash in your application.

在这里为了得到正确的语义,则必须直接返回一个IntPtr。然后使用Marshal.PtrToString *为了得到一个管理字符串值。您可能还需要释放取决​​于foo的执行本机内存,但将

In order to get the correct semantics here you must return an IntPtr directly. Then use Marshal.PtrToString* in order to get to a managed String value. You may still need to free the native memory but that will dependent upon the implementation of foo.

这篇关于PInvoke的为C函数返回的char *的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆