.net - 如何在 C# 中声明联合?

标签 .net interop

观察以下示例代码:

struct DDD
{
  [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 512, ArraySubType = UnmanagedType.I1)]
  byte[] x;
}

struct BBB
{
  DDD x;
}

struct CCC
{
  DDD x;
  ulong y;
  ulong z;
}

[StructLayout(LayoutKind.Explicit)]
struct AAA
{
  [FieldOffsetAttribute(0)]
  BBB a;
  [FieldOffsetAttribute(0)]
  CCC b;
}

不幸的是,无法加载AAA,尝试执行new AAA()失败,并出现System.TypeLoadException:无法从程序集'加载类型'AAA' Shunra.Common,Version=1.0.0.0,Culture=neutral,PublicKeyToken=807fc02bc4ce69db',因为它在偏移量 0 处包含一个对象字段,该对象字段未正确对齐或与非对象字段重叠。

如何应对?

谢谢。

编辑:

顺便说一句,这是 PInvokeTool 创建的 MINIDUMP_CALLBACK_INPUT 结构互操作的精简版本(原始结构在 DbgHelp.h 中定义)

最佳答案

问题是,无论您为 MarshalAsAttribute 指定什么,数组就是数组,就是托管对象。为了使您的代码正常工作,您必须摆脱托管数组。为此,您有两种选择:

选项 1:

将数组转换为固定大小的缓冲区,这意味着将 DDD 的定义更改为:

unsafe struct DDD {
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 512, ArraySubType = UnmanagedType.I1)]
    fixed byte x[512];
}

(我不确定是否需要 MarshalAsAttribute,但我对此表示怀疑。)

现在您使用的是不安全的结构,因此您必须使用/unsafe 开关进行编译。

选项 2:

将数组转换为 512 字节的成员。最简单的方法是使用 64 个长整型:

struct DDD {
    long x1;
    long x2;
    long x3;
    ...
}

编辑:澄清。

关于.net - 如何在 C# 中声明联合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1805179/

相关文章:

.net - .Net 开发人员使用的第 3 方控件是什么

.net - 如何在 VS 2008 中很好地重新格式化 XAML?

.net - 将 .Net 类公开给 COM,同时它具有私有(private)泛型类型成员

C# + COM,修改参数中的数组

.net - 将 app.config 与互操作控件结合使用

c# - 将 RTF 字符串合并为一个

.net - 如何将分层数据从 DataTable 转换为 JSON

C# 为字节数组或图像创建哈希

c# - 我需要做什么才能在 C# 中实现 "out of proc"COM 服务器?

c# - 基于非零的多维数组