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

我想将一个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。这只是一个猜测。

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

回答:

这是一个有点含糊不清你要在这里做什么。本地代码可以将float*视为指向float的指针或float值的数组。

如果本机代码认为它是指向单个的指针float那么你的代码就好了。将float设置为ref的托管指针和原生地址将会正确编组。

如果本机代码认为它是一个float值的数组,那么您很可能有问题。这将是把它当作长度为1的数组对于任何其他长度的角落情况下工作,但您需要在托管签名

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

以上是 是否将float []作为ref float传递给非托管代码是个好主意? 的全部内容, 来源链接: utcz.com/qa/260956.html

回到顶部