0

我认为这与我对 nlog C++ API 的使用有关(我在 nlog 论坛上的问题在这里);我在这里提出这个问题的目的是让更广泛的受众了解我的问题,也许还可以获得一些关于 VB6 IDE 未能在我的特定场景中构建的更一般的想法。

简而言之,我遇到的问题是我无法构建引用非托管 C++ 组件的 VB6 组件,这些组件调用了 nlog 的 C\C++ API(在 NLogC.DLL 中定义)。构建问题不会在编译期间发生,它们是在构建二进制文件时发生的,这向我暗示这是某种链接器类型问题?对如何生成 VB6 二进制文件知之甚少。生成了 VB6 二进制文件,但它在调用后不久就损坏并崩溃。

有没有人对VB6有过类似的经历(不一定与nlog或C++有关)?

编辑:感谢所有对这个相当晦涩的问题的回应。不幸的是,仍然没有进展;我发布后的发现:

  1. “调整”编译选项似乎对解决这个问题没有帮助。
  2. 从“空白”VB6 项目添加对启用 nlog 的 C++ 组件的引用不会使其崩溃或导致奇怪的构建问题。所以这不是“原生”VB6 问题,可能是 nlog 与其他引用组件使用的各种组件和 3rd 方库之间的交互问题?
  3. 至于 C++ 调用约定:启用 nlog 的 C++ 组件 - 据我所知 - 符合这些约定,并且在 VB6 引用时确实可以正常工作,只要它不进行任何 nlog API 调用。不确定 nlogc.DLL 本身是否兼容 VB6,但我认为这无关紧要,因为 API 调用是从 C++ 组件进行的;VB6 不应该知道或关心 C++ 组件所引用的内容(据我对此的理解......)

编辑2:我还应该注意构建过程中获得的错误消息是:“加载过程中的错误。有关详细信息,请参阅“xxx”。当我打开日志文件时,里面只有:“无法加载控制 xxx”。有趣的是,如果我要再次尝试构建,对该特定控件的所有引用都会从该特定项目中消失,从而导致编译错误。

4

6 回答 6

2

通过在我的非托管 C++ 代码中使用 NLog 的 COM 接口 (NLog.ComInterop.DLL) 解决了这个问题。不像 C\C++ API 那样容易,但至少它不会使我的 VB6 组件崩溃。

于 2008-09-30T06:47:08.003 回答
0

我会尝试调整ProjectProperties菜单、Compile面板中的一些Compile选项,以查看它们是否会产生任何关于出现问题的额外提示。

例如,如果您将可执行文件编译为p 代码而不是本机代码,它是否仍然在启动时崩溃。

于 2008-09-25T04:06:41.420 回答
0

运行已编译的二进制文件时会收到什么错误消息?

我怀疑编译器/链接器是问题所在:VB6 项目中的项目引用没有链接到最终的可执行文件中。VB6 中的项目引用实际上是对 COM 类型库的引用(可能嵌入也可能不嵌入 .dll 或其他二进制文件类型)。项目参考主要有两个目的:

  1. IDE 从引用的类型库中提取类型信息,然后将其显示在对象浏览器(以及 Intellisense 下拉菜单中)

  2. 在编译时,编译器提取存储在引用库中的类型信息,包括您实例化的每个类的 CLSID,并将此数据嵌入到可执行文件中。这允许您的可执行文件创建包含在您引用的库中的类的实例。

请注意,编译后的二进制文件不链接到引用库中的任何代码,甚至不包含引用库的文件名。最终的可执行文件只包含在运行时实例化 COM 对象所需的 CLSID 和其他类型信息。

问题很可能出在 NLog 上,或者您如何从代码中调用它,而不是 VB6 编译过程中出现问题。

于 2008-09-25T15:07:46.307 回答
0

如果您认为这可能是链接器问题,则应该以同样的方式使其崩溃:

  1. 创建一个新的标准项目(任何类型)
  2. 添加一个新模块并将“声明”语句复制到其中
  3. 编译

如果它没有崩溃,那就是别的东西。

于 2008-09-25T21:17:35.903 回答
0

这将有助于准确描述错误或截屏。

要检查的一件事是您构建的 NLogC.DLL 或 C++ DLL 是否定义了正确的调用约定。基本上,除了 STDCALL 调用约定之外,您不能修改 DLL 函数名称或使用任何东西。如果在创建 C++ DLL 时没有考虑到这两件事,那么它将无法与 VB6 一起使用。

MSDN 关于调用约定的文章。

于 2008-09-26T13:28:32.843 回答
0

“无法加载控件 xxx”错误可能由 .oca 文件引起,这些文件是从与当前使用的 .ocx 版本不同的版本创建的。如果是这种情况,删除 .oca 文件会有所帮助。

于 2008-09-30T17:40:28.667 回答