C# 从不安全结构获取固定数组值

C# 从不安全结构获取固定数组值,c#,C#,我使用的是一个外部C库,它附带了一个C#包装文件,其中包含一个结构,如(除其他外): 我可以通过向该结构添加其他方法来获取值: public double[] CopyFixedDoubleArray() { double[] result = new double[3]; fixed (double* pDst = result) { fixed (double* pSrc = Values) { double*

我使用的是一个外部C库,它附带了一个C#包装文件,其中包含一个结构,如(除其他外):

我可以通过向该结构添加其他方法来获取值:

public double[] CopyFixedDoubleArray()
{
    double[] result = new double[3];
    fixed (double* pDst = result)
    {
        fixed (double* pSrc = Values)
        {
            double* pd = pDst;
            double* ps = pSrc;
            for (int i = 0; i < result.Length; i++)
            {
                *pd = *ps;
                pd++; ps++;
            }
        }
    }
    return result;
}
public double[]CopyFixedDoubleArray()
{
double[]结果=新的double[3];
固定(双*pDst=结果)
{
固定(双*pSrc=值)
{
双*pd=pDst;
双*ps=pSrc;
for(int i=0;i
但这不是我想要的,因为我不想接触包装文件(以避免将外部文件保留在SCM存储库中)。无论我如何尝试从该结构外部获取值,都会导致以下错误:

只能通过局部变量或字段访问固定大小的缓冲区

我所尝试的:

  • double a=data.Values[2]
  • 双a;不安全{a=data.Values[2];}
  • 双a;固定(double*p=data.Values){a=p[2];}
  • fixed(双a=data.Values[2]){/*使用*/}

有什么办法可以解决这个问题吗?

突然,我想到了“扩展方法”这个词。是的,我让它工作:

public static double[] CopyFixedDoubleArray(this Data data)
{
    unsafe
    {
        return new[] { data.Values[0], data.Values[1], data.Values[2] };
    }
}

与其修补你的代码,你有没有考虑过把它交给封送员?这就是它的全部目的:帮助实现本机互操作,同时让您编写纯托管代码

您必须像下面这样声明您的
struct

[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct Data
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
    public double[] Values;
};
当封送拆收器填充此结构时(通过指针的直接函数调用,或通过在字节缓冲区顶部映射
struct
),它将分配适当的数组并将其内容复制到上。这会使您的整个函数过时,但如果您真的想使用,只需使用
Array.Copy
(或Linq等效工具)


请注意,没有更多的
不安全的
修改器。您可以在部分受信任的环境中运行此程序,而不会出现任何问题

显示如果
struct Data
包含
CopyFixedDoubleArray()
方法,将调用
CopyFixedDoubleArray()
的代码。
double a=Data.CopyFixedDoubleArray()[2]因此,
数据数据2=数据;双a;不安全的{a=data2.Values[2];}
不起作用?不,会导致错误hmm,让我们等待C#gurus。是的,这也是我编写包装器的方式。但这里的情况并非如此,因为它来自第三方,只要您知道该选项存在!这太奇怪了。扩展方法可以工作,尽管结构上的相同方法不能工作。我想知道为什么。顺便说一句,救了我一天,谢谢分享!
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct Data
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
    public double[] Values;
};