[英]free allocated memory when interoping c++
填充包含字符串的stuct数组,我测试了一个发现,在c#中它通过指针执行得更快:
struct name{
int intv;
IntPtr strv;
}
当通过GetPacksPtr()
实现时:(请参见下面的代码/签名),这就是我的编码方式,并且不确定我是否做对了...
说ArrL = 10,000
DataPack* DataPackArr;
List<DataPack> DataPackLst = new List<DataPack>(ArrL);
GetPacksPtr(ArrL, &DataPackArr);
DataPack* CurrentPack = DataPackArr;
for (int i = 0; i < ArrL; i++, CurrentPack++)
{
DataPackLst.Add(new DataPack() { strv = CurrentPack->strv, intv = CurrentPack->intv });
}
我在哪里可以释放分配的内存,因为__stdcall
定义了非托管代码必须释放内存,但是谁是所有者(“契约”)……这令人困惑,我试图以最低的性能命中率来释放分配。
C ++
extern "C" __declspec(dllexport) void __stdcall GetPacksPtr(int size, DataPack** DpArrPtr )
{
*DpArrPtr = (DataPack*)CoTaskMemAlloc( size * sizeof( DataPack ));
DataPack CurPackPtr = *DpArrPtr;
char aStr[]= "abcdefgHi";
for ( int i = 0; i < size; i++,CurPackPtr++ )
{
CurPackPtr->IntVal=i;
CurPackPtr->buffer = (char*)malloc(sizeof(aStr));
strcpy(CurPackPtr->buffer, aStr);
}
}
C#
[DllImport("exported.dll", CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurity]
public static extern void GetPacksPtr(int RaySize, DataPack** DataPackArr);
是的,当你手动分配内存,它是当然的更快,这是很常见的,你需要另外一个(这部分我不知道该说些什么,因为你的一切混合) Ç功能这样的
__declspec(dllexport) void __stdcall FreePacksPtr(int size, DataPack *DpArrPtr)
{
for (size_t i = 0 ; i < size ; ++i)
free(DpArrPtr[i].buffer);
CoTaskMemFree(DpArrPtr);
}
然后,在C#中,只要不再需要指针,就调用FreePacksPtr()
。
注意 :事实上,您需要extern "C"
意味着C#代码期望从dll加载确切的符号,似乎您必须指示microsoft编译器编译c代码而不是c ++,我不是100%当然可以,但是Microsoft编译器将这些混合在一起。
当您分配非托管内存时,您必须释放它-但是没有关于谁负责释放的规则。
在不受管理的世界中,通常的策略是为每个需要释放的资源都拥有一个“所有者”,这种所有权是释放对象的责任。
如果函数A分配了一块内存,然后将指针传递给函数B,则有两种选择:
A仍然是所有者,完成后将释放内存,B不必处理释放内存的问题,但也无法保存指针供以后使用,因为A可以随时将其释放
所有权从A转移到B,现在B负责释放,并且B返回后A不能对指针执行任何操作,因为B可以随时将其释放
请注意,函数原型中没有任何东西可以表示所有权,所有这些都是通过程序员A和程序员B之间的协议达成的(通常称为“按合同”)
现在,要使事情变得更复杂,可以从中分配许多内存块(称为“堆”),释放时,需要释放到用于分配的同一堆中。
Windows管理着几个堆,.net Marshal类具有将内存释放到其中的方法。
malloc使用的堆不是其中之一,必须通过在与malloc相同的dll中调用free来释放malloc分配的内存。
最后但并非最不重要的一点是,分配和释放内存是您在非托管代码中可以执行的最慢的操作之一,如果您执行了很多操作,则会遇到诸如内存碎片和引用局部性之类的麻烦(此答案足够长,而没有进入他们)
分配和释放策略对非托管代码的性能有巨大影响-这不会对您的性能产生最小的影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.