gpt4 book ai didi

c# - P/Invoke Marshaling float *&

转载 作者:太空宇宙 更新时间:2023-11-03 10:46:08 25 4
gpt4 key购买 nike

我正在尝试使用 P/Invoke 从 C# 应用程序调用一些 C++ DLL 函数。他们的标题是:

void f1(float* a, float* b, long n, float* r);

void f2(float* a, float* b, long n, float*& r);

用法上的区别在于,f1 接收一个在函数外部创建的数组作为第四个参数,而 f2 保留内存并在其中填充数组。我可以使用 f1 声明

[DllImport("myLib.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void f1(float[] a, float[] b, uint n, float[] r);

并从程序中调用它:

float[] a = new float[] { 1,2,3 };
float[] b = new float[] { 4,5,6 };
uint n = 3;
float[] r = new float[n];
f1(a,b,n,r);

这很有效。

但是我不知道如何正确使用f2。我声明它,因此:

[DllImport("myLib.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void f2(float[] a, float[] b, uint n, out float[] r);

当我用未初始化的数组调用 f2 时:

float[] r = null;
f2(a,b,n, out r);

当我尝试访问 r 时抛出 System.AccessViolationException。

有什么建议吗?提前致谢。

最佳答案

P/Invoke 编码(marshal)拆收器无法将最后一个参数作为数组处理。在 .Net 中,数组必须有一个与其关联的大小,而在 C 中,它们只是内存块。由于 marhsaler 不知道数组的大小,因此无法处理它。但是,您可以使用 IntPtr

手动处理它
[DllImport("myLib.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void f2(float[] a, float[] b, uint n, out IntPtr rPtr);

然后您可以使用 Marshal.Copy 从指针中提取数组值:

float[] r = new float[size];
Marshal.Copy(rPtr, r, 0, size);

此外,您还需要在 DLL 中调用一个函数来释放 f2 为数组分配的内存,因为没有任何方法可以释放在 C DLL 中分配的内存。

关于c# - P/Invoke Marshaling float *&,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23347325/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com