我使用的外部C库附带了一个包含结构的C#包装器文件(在许多其他方面):
[StructLayout(LayoutKind.Sequential, Pack = 8)]
unsafe public struct Data
{
public fixed double Values[3];
};
我可以通过向该结构添加一个额外的方法来获取值:
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;
}
但这不是我想要的,因为我不想触摸包装文件(以避免将外部文件保留在我们的SCM存储库中)。无论我尝试从结构外部获取值,都会导致以下错误:
固定大小的缓冲区只能通过本地或字段访问
我尝试过的事情:
double a = data.Values[2];
double a; unsafe { a = data.Values[2]; }
double a; fixed (double* p = data.Values) { a = p[2]; }
fixed (double a = data.Values[2]) { /* use a */ }
有没有办法解决这个问题?
答案 0 :(得分:1)
突然间,这个词的扩展方法&#39;克服了我的想法。是的,我有它的工作:
public static double[] CopyFixedDoubleArray(this Data data)
{
unsafe
{
return new[] { data.Values[0], data.Values[1], data.Values[2] };
}
}
答案 1 :(得分:-1)
您是否考虑过将其推送给编组员,而不是修补您的代码?这就是它的全部目的:在让你编写纯托管代码的同时协助本地互操作。
你必须声明你的struct
:
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct Data
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public double[] Values;
};
当这个结构由编组器填充时(通过指针直接调用函数,或者从字节缓冲区顶部映射struct
),它将分配正确的数组并复制其内容。这会使您的整个功能过时,但如果您真的想要,可以简单地使用Array.Copy
(或等效的Linq)。
请注意,不再有unsafe
修饰符。您可以在部分受信任的环境中运行它,没有任何问题!