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

我试图将程序从VB6移植到C#,读取二进制文件并解析它。 我没有编译时错误或警告但是当我尝试运行它时,在它进入Main()之前它会抛出exception

 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; } 

经过一些googleing之后,我认为我错过了Pack = 1但补充说并没有解决我的问题。

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

编辑:

第一个字符长度为一个字节,这里是文件中第一个记录的hex转储

 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:将我的代码更改为以下内容以消除所有其他可能的错误,它仍然给我相同的exception

 [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都没有工作。

我觉得

Active As String * 1

翻译成

烧焦

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

说明:

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

Dim str As String str =“help”我们本身并没有定义Unicode字符数组。 我们正在定义一个名为BSTR的数据类型的成员,它是Basic String的缩写。 事实上,BSTR是指向以空字符结尾的Unicode字符数组的指针,该数组前面是4字节长度的字段。

编辑:

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

从我看到的,你混淆了“Active”和“TitleLength”的声明,似乎完全被跳过了……

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

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

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