是否将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个浮标阵列,你有两个选择:
- 马歇尔到底。
- 使用不安全的代码直接锁定和传递托管内存。
下面是整理方法:
[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