填充包含字符串的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
定义了非托管代码必须释放内存,但谁是“通过cotract”的所有者...这令人困惑,我正在尝试负责释放分配以最低性能命中
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);
答案 0 :(得分:2)
是的,当你手动分配内存时这是很常见的,它当然更快,你需要另一个(这部分我不知道该说些什么,因为你混合了一切)c这样的功能
var errorsHtml = '<div class="alert alert-danger"><ul>';
errorsHtml += '<li>' + errors.errors.join('</li><li>') + '</li>';
errorsHtml += '</ul></div>';
然后在你的C#中,只要你不再需要指针就调用__declspec(dllexport) void __stdcall FreePacksPtr(int size, DataPack *DpArrPtr)
{
for (size_t i = 0 ; i < size ; ++i)
free(DpArrPtr[i].buffer);
CoTaskMemFree(DpArrPtr);
}
。
注意:您需要FreePacksPtr()
的事实意味着C#代码期望从dll加载确切的符号,似乎您必须指示Microsoft编译器进行编译c代码而不是c ++,我不是100%肯定,但微软编译器混合了这些。
答案 1 :(得分:2)
当您分配非托管内存时,您必须释放它 - 但是没有关于谁负责释放的规则。
在非管理的世界中,为每个需要释放的资源拥有“所有者”是一种常见的策略,这种所有权是释放对象的责任。
如果函数A分配一块内存然后将指针传递给函数B,则有两个选项:
A仍然是所有者并且在完成后将释放内存,B不必处理释放内存但也无法保存指针以供以后使用,因为它可以随时被A <释放/ p>
所有权从A转移到B,现在B负责释放,A在B返回后无法对指针做任何事情,因为它可以随时被B释放
请注意,函数原型中没有任何内容代表所有权,这完全是由编写A的程序员和编写B的程序员之间的协议(通常称为“按合同”)
现在,为了使事情变得更复杂,可以分配许多内存块(称为“堆”),当你释放时,你需要释放到用于分配的同一堆中。
有几个由Windows管理的堆,而.net Marshal类有释放内存的方法。
malloc使用的堆不是其中之一,malloc分配的内存必须通过在调用malloc的同一个dll中调用free来释放。
而且,最后但并非最不重要的一点是,分配和释放内存是你可以在非托管代码中做的最慢的事情之一,如果你做了很多,你会遇到内存碎片和引用位置等问题(这个答案是足够长,没有进入他们)
分配和释放策略会对非托管代码的性能产生巨大影响 - 这对您的性能影响不大。