【问题标题】:C# pinvoke of C function returning char* [duplicate]C函数的C#pinvoke返回char * [重复]
【发布时间】:2014-12-14 10:40:39
【问题描述】:

这是我想出的:

非托管函数:

extern  "C" __declspec(dllexport) char* callme(const char * sing) {
    char buf[10];
    sprintf(buf,"hey %s",sing);
    return buf;
}

调用函数:

class Program
{

    [DllImport("testnonclr.dll", CharSet = CharSet.Auto, CallingConvention =
        CallingConvention.Cdecl)]
    public static extern IntPtr callme([In,MarshalAs(UnmanagedType.LPStr)]
        string sing);

    static void Main(string[] args) {
        Console.Write( Marshal.PtrToStringAuto (callme("baby")  ));
        Console.ReadLine();  
    }
}

结果:一堆乱码

好的,感谢一些用户的帮助和更多的挖掘,这就是我最终做的:

extern  "C" {
 __declspec(dllexport)  char* __stdcall callme(const char * sing)
{
static char *buf=NULL;
    char fubb[10];


sprintf(fubb,"hey %s",sing);
ULONG usize=strlen(fubb)+sizeof(char);
buf=(char *)::GlobalAlloc (GMEM_FIXED,usize);


strcpy(buf,fubb);

return buf;

}

}

和 C#:

class Program
{

    [DllImport("testnonclr.dll", CharSet = CharSet.Unicode, CallingConvention =    C  
    CallingConvention.StdCall )]
   [return: MarshalAs(UnmanagedType.LPStr)]
    public static extern string callme([In, MarshalAs(UnmanagedType.LPStr)] string sing);
    static void Main(string[] args)
    {
        string rrr = callme("baby"); 
        Console.WriteLine(rrr); 


        Console.ReadLine();  
    }

}

【问题讨论】:

标签: c# c pinvoke marshalling


【解决方案1】:

您不能返回指向局部变量的指针,因为它们是在堆栈上分配的(当函数返回时堆栈可能会被破坏)。

您需要在 C 函数的堆上分配内存(最好使用CoTaskMemAlloc,以便 CLR 稍后可以释放内存)并返回指向该内存的指针。

附带说明一下,编组时可以直接返回string(假设它是c null 终止的unicode 字符串),无需返回IntPtr

更多信息在这里:http://limbioliong.wordpress.com/2011/06/16/returning-strings-from-a-c-api/

【讨论】:

猜你喜欢
  • 2010-09-27
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-04
  • 2023-04-05
相关资源
最近更新 更多