繁体   English   中英

System.TypeLoadException:无法从程序集“y”加载类型“x”

[英]System.TypeLoadException: Could not load type 'x' from assembly 'y'

我正在尝试将程序从 VB6 移植到 C# 中,该程序读取二进制文件并对其进行解析。 我没有收到编译时错误或警告,但是当我尝试运行它时,甚至在它进入Main()之前它就会抛出异常

System.TypeLoadException was unhandled
  Message=Could not load type 'Conversion.DataStructures.ClientOld' from assembly
     'SandboxConsole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because
     it contains an object field at offset 1 that is incorrectly aligned or overlapped
     by a non-object field.
  Source=SandboxConsole
  TypeName=Conversion.DataStructures.ClientOld
  StackTrace:
       at sandbox.Program.Main(String[] args)
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

这是旧 VB6 代码的示例

Private Type SrcClientOld
    Active As String * 1            '0
    titleLength As Byte             '1
    title As String * 8             '2
    lastNameLength As Byte          '10
    LastName As String * 25         '11
    (...)
    AddedBy As String * 3           '369
    junk7 As String * 22            '372
End Type                            '394

这是我写的 C# 代码

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 1)]
struct ClientOld
{
    [FieldOffset(0)]
    public byte Active;

    [FieldOffset(1)]
    [MarshalAs(UnmanagedType.AnsiBStr)]
    public string Title;

    [FieldOffset(10)]
    [MarshalAs(UnmanagedType.AnsiBStr)]
    public string LastName;

    (...)

    [FieldOffset(368)]
    [MarshalAs(UnmanagedType.AnsiBStr)]
    public string AddedBy;

    [FieldOffset(372)]
    [MarshalAs(UnmanagedType.LPArray, SizeConst = 22)]
    public byte[] Unknown7;
}

经过一些谷歌搜索后,我认为这是我错过了Pack = 1但添加并没有解决我的问题。

关于做什么的任何其他建议?

编辑:

第一个字符是一个字节长,这里是文件中第一条记录的十六进制转储

A.Dr.......Smith....................
41 03 44 72 2E 00 00 00 00 00 05 53 6D 69 74 68 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|  |  |                       |  ^LastName
|  |  ^title                  ^lastNameLength
|  ^titleLength
^Active

EDIT2:将我的代码更改为以下内容以消除所有其他可能的错误它仍然给我同样的异常

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 1)]
struct ClientOld
{
    [FieldOffset(0)]
    public byte Active;

    [FieldOffset(1)]
    [MarshalAs(UnmanagedType.AnsiBStr)]
    public string Title;
}

我尝试了 fieldoffset(1) 和 2 都没有工作。

我觉得

以字符串形式激活 * 1

翻译成

字符

在 Unicode 语言中不是 1 字节,所以下一个字段偏移量不应该是 1,但如果我正确理解以下内容,可能是 7:。

解释:

这是理解字符串的关键:当我们编写代码时:

Dim str As String str = "help" 我们没有定义 Unicode 字符数组本身。 我们正在定义一个名为 BSTR 的数据类型的成员,它是基本字符串的缩写。 实际上,BSTR 是指向以 4 字节长度字段开头的以空字符结尾的 Unicode 字符数组的指针。

编辑:

通过您的转储,似乎第二个成员应该有 [FieldOffset(2)] 因为如果不是,它将与前一个成员重叠。 (编辑误报,我看到一个 00 有一个 03)。

据我所知,您混淆了似乎完全跳过的“Active”和“TitleLength”的声明。

尝试使用 IntPtr 而不是字符串,然后调用Marshall.PtrToStringAnsi

您需要保留旧代码的确切布局才能使此转换生效。 二进制文件将以上次保存的格式存储,因此您必须准确地复制它,即使这意味着在任何地方都使用字节和字节 arrays。

如果您想改用新布局,您可以使用旧布局创建一个版本,将它们加载复制值到您的新格式,然后用新格式将它们保存回来。 从那时起,您可以使用新布局加载它们。 在这种情况下,您的新格式的选择是无穷无尽的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM