gpt4 book ai didi

visual-c++ - C++/CLI Wrapper DLL TypeLoadException 字段太多

转载 作者:行者123 更新时间:2023-12-02 01:11:19 25 4
gpt4 key购买 nike

我有原生(非托管)C++ DLL,它们被单个 C++/CLI dll 包装(通过 .lib 文件链接)。这些非托管 C++ DLL 有相当多的类,其中包含大量方法和大量常量数据(例如字符串、十六进制值等),这些数据在包含的 header 中定义。

但对于 C++/CLI 包装器 DLL,它只是 native dll 的包装和编码层。然而,它的二进制大小与 native dll 一样大。我相信这会导致我达到硬编码限制,当它被 C# 应用程序加载时会抛出异常:System.TypeLoadException:内部限制:字段过多

C# 应用程序永远不会使用 native DLL header 中定义的字段。

它能够通过启用字符串池(减少几 MB)来缓解这个问题,但它看起来像是一个 hack。

为什么 DLL 的简单包装与该 DLL 的大小相同?有没有一种方法可以标记常量数据,使 C# 应用程序不会加载它们?

最佳答案

您陷入了一个很常见的陷阱,C++/CLI 编译器工作得太好了。当 #pragma managed 或/clr 生效时,它能够将任何 C++03 兼容的 native C++ 代码编译成 IL。在运行时也能很好地工作,它通过抖动实时编译为机器代码,就像常规托管程序一样。

这是个好消息。坏消息是这段代码不会像托管代码那样执行。它没有得到验证,也没有得到垃圾收集器的喜爱。它的运行效率也不如定期编译的 C++ 代码,您错过了 C++ 代码优化器获得绝对最佳机器代码的额外时间。

还有使您的程序爆炸的一个限制。任何全局变量和自由函数都被编译成隐藏的成员 <Module>类(class)。必需,因为 CLR 不支持全局变量。托管类的成员获得元数据 token ,这是一个在元数据表中唯一标识它们的数字。 token 是一个 32 位值,低 16 位用于对它们进行编号。 Kaboom 当你创建一个 <Module>拥有超过 65535 名成员的类(class)。

显然,这一切都是不受欢迎的。您需要更多地关注哪些代码被编译为 IL 以及哪些代码被编译为机器代码。您的 native C++ 源代码应该在没有有效的/clr 选项的情况下进行编译。按住 Shift 键并单击选择这些文件并设置选项。必要时,使用#pragma un/managed 在一个源代码文件中来回切换编译器。

关于visual-c++ - C++/CLI Wrapper DLL TypeLoadException 字段太多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17117471/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com