将C#中的字符串传递给c ++ .dll会扰乱数据

时间:2016-02-15 21:05:38

标签: c# c++ dll

我有一个c ++ dll,代码如下:

extern "C"
{
    const char *SaveDate;

    __declspec(dllexport) void SetDate(const char *date)
    {
        SaveDate = date;

        std::cout << "date: " << SaveDate  << std::endl;

    }
}

当我在该函数中打印值时,它会打印

'date: 20160215' 

但是当我从另一个函数中获取'SaveDate'变量并打印它时,它会打印

'104'

我的C#是:

[DllImport("XmlRecord.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetSlate(string date);


public bool SetupRec()
{
    string Date = DateTime.Now.ToString("yyyyMMdd");
    SetSlate(Date);
}

为什么这个值在c ++ dll中被扰乱?

谢谢。

1 个答案:

答案 0 :(得分:4)

如果你使用P / Invoke,那么传递给你C函数的任何参数在通话期间都是有效的

如果要重用输入字符串,则需要复制它。你得到的那个作为参数将在通话后被释放(你甚至不知道何时)。只需将其保存到std::string,而不是保留const char *

如果您绝对想避免复制数据,可以使用一些机制,但是您必须在C#端采取适当的预防措施,因为允许GC随时在内存中移动对象。登记/> 这涉及长期对象固定(使用GCHandle类),这是GC的障碍,因此最好避免使用。如果可以将数据有效性限制为单个堆栈帧,则可以使用短期固定(使用fixed语句)。然后,您必须将数据作为IntPtr传递给C函数,以绕过.NET封送。