• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

是否将float []作为ref float传递给非托管代码是个好主意?

c/c++ 来源:thalm 8次浏览

我想将一个float []传递给C方法。的C签名是这样的:是否将float []作为ref float传递给非托管代码是个好主意?

EXTERN int process_raw(float *inBuffer, float *outBuffer); 

在C#中的签名是:

public static extern int process_raw(ref float inBuffer, ref float outBuffer); 

会是有问题的同一个引用传递数组的第一个成员:

process_raw(ref someArray[0], ref anotherArray[0]) 

的感谢!

编辑:当然重要的是要知道什么C代码与浮动:它会将它们视为数组,并将读取inBuffer的值,并将值写入outBuffer。如下所述,问题是在PInvoke调用期间整个内存是否被锁定?

编辑2:另一个评论。我选择了故意裁判浮动,因为我也很想做的事情一样:

fixed(byte* outBuff = buffer) 
{ 
    Process(ticks, ref aFloat, ref ((float*)outBuff)[0]); 
} 

在这种情况下,它应该是没有问题的,因为指针反正固定的,但对于普通阵列如上遗体的问题。


===========解决方案如下:

有使用一个实际的数组是参与P中没有自动针/调用。 P/Invoke通过编组严格执行! (没有不安全的代码)编组意味着分配(非托管)内存和复制。在封面下面,可能会有一个针对复制持续时间,但不是在本机函数调用期间。

如果你需要传递的进出本机功能的64个浮标阵列,你有两个选择:

  1. 马歇尔到底。
  2. 使用不安全的代码直接锁定和传递托管内存。

下面是整理方法:

[DllImport(...)] 
private extern static int process_raw([In] float[] inBuffer, [Out] float[] outBuffer); 

请注意,我说的[IN]和[OUT]属性,因为他们告诉的Marshaller(在)没有对方式复制出来(出)不要在途中复制。在编写ap/invoke声明时总是考虑这些属性是一个好主意。

这里是不安全的方法:

[DllImport(...)] 
private extern static unsafe int process_raw(float * inBuffer, float * outbuffer); 

public static unsafe int Process(float[] inBuffer, float[] outBuffer) 
{ 
    // validate for null and Length < 64 
    fixed (float * pin = inBuffer) 
    fixed (float * pout = outBuffer) 
     return process_raw(pin, pout); 
} 

展开后评论

这是我的理解是现Marshaller能够“在某些情况下”选择钉住管理内存而不是分配非托管记忆和复制。问题在于:什么情况?

我不知道答案,但我有一个怀疑:当本地DLL是某些系统DLL。这只是一个猜测。

这对你和我来说意味着什么很简单:总是从编组方法开始。如果您遇到性能问题,并且分析器告诉您本地通话耗费大量时间,那么您可以尝试不安全的方法并再次对其进行配置。如果没有显着的改善,那么你只希望优化本地电话。


版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)