C#调用C++
C#与C++之间传递结构体数据,运行数次之后就会异常。
报错信息:
托管调试助手“ContextSwitchDeadlock”在“D:\Work\code\VS\Test2015\Test2015\CharpCaller\bin\Debug\CharpCaller.vshost.exe”中检测到问题。
其他信息: CLR 无法从 COM 上下文 0xb99ef8 转换为 COM 上下文0xb99fb0,这种状态已持续 60 秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长的操作。这种情况通常会影响到性能,甚至可能导致应用程序不响应或者使用的内存随时间不断累积。要避免此问题,所有单线程单元(STA)线程都应使用泵式等待基元(如 CoWaitForMultipleHandles),并在运行时间很长的操作过程中定期发送消息。
C++ .h文件
struct Person
{
public:
int id;
char name[256];
};
extern "C"
{
__declspec(dllexport) void GetPerson(Person &person);
};
C++ .cpp文件
void GetCPerson(CPerson &person)
{
person.id = 1;
strcpy_s(person.name, 32, "名字Name-1");
}
C#
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct Person
{
public int id;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst =256)]
public string name;
}
[DllImport("MFCLib.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "GetPerson")]
extern static void GetPerson(IntPtr person);
调用:
Person p;
for (int i = 0; i < 100000; i++)
{
int size = Marshal.SizeOf(typeof(Person));
IntPtr pp = Marshal.AllocHGlobal(size);
GetPerson(pp);
p = (Person)Marshal.PtrToStructure(pp, typeof(Person));
Marshal.FreeHGlobal(pp);
Console.WriteLine("Person id: {0}, name: {1}", p.id, p.name);
}