对于前。我有c#COM对象具有这样的功能:
int GetString([In, Out, MarshalAs(UnmanagedType.LPStr)]ref string str)
然后我从c ++调用int(在c ++ COM对象中使用#import
关键字),在生成的包装器方法中声明为:
GetString(LPSTR * str, long * retVal)
我这样称呼它:
char myStr[40];
LPSTR buf = (LPSTR)myStr;
LPSTR pBuf = &buf;
pComObject->GetString(pBuf);
奇怪的是:
1)未填充myStr,并且buf
值已更改(调用后与myStr
不一致)因此,我认为c#marshaller分配新的内存块
2)如果c#分配内存,那么我应该调用free(buf);
吗?
答案 0 :(得分:3)
是的,客户端应该释放内存。 在这种情况下,应该使用CoTaskMemFree函数来释放接收到的缓冲区。由于缓冲区可能未在客户端堆上分配。 CoTaskMemFree将调用适当的删除器。
答案 1 :(得分:2)
是的,我认为你需要在调用GetString函数后释放C ++代码中的缓冲区。
根据COM "Memory Management Rules",调用者(您的C ++代码)应该释放作为输出参数返回的内存。在输入/输出参数的情况下,被调用者(CLR和您的C#代码)可以释放您传入的参数的内存,然后为输出值分配新内存,并且调用者也有责任释放记忆。