我有一个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中被扰乱?
谢谢。
答案 0 :(得分:4)
如果你使用P / Invoke,那么传递给你C函数的任何参数在通话期间都是有效的。
如果要重用输入字符串,则需要复制它。你得到的那个作为参数将在通话后被释放(你甚至不知道何时)。只需将其保存到std::string
,而不是保留const char *
。
如果您绝对想避免复制数据,可以使用一些机制,但是您必须在C#端采取适当的预防措施,因为允许GC随时在内存中移动对象。登记/>
这涉及长期对象固定(使用GCHandle
类),这是GC的障碍,因此最好避免使用。如果可以将数据有效性限制为单个堆栈帧,则可以使用短期固定(使用fixed
语句)。然后,您必须将数据作为IntPtr
传递给C函数,以绕过.NET封送。