奇怪的VB6构建问题(与nlog有关)

时间:2008-09-25 03:37:56

标签: vb6 build nlog

我认为这与我使用nlog C ++ API有关(我在nlog论坛上的问题是here);我在这里提出这个问题的目的是为了让更广泛的观众了解我的问题,也许还会在VB6 IDE无法在我的特定场景中构建更多一般性的想法。

简单地说,我遇到的问题是我在构建VB6组件时遇到问题,这些组件引用了非托管C ++组件,这些组件调用了nlog的C \ C ++ API(在NLogC.DLL中定义)。在编译期间没有出现构建问题,它们是在构建二进制文件时发生的,这表明它是某种链接器类型问题?不知道如何生成VB6二进制文件。生成VB6二进制文件,但它被破坏并在调用后立即崩溃。

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

编辑:感谢所有对这个相当模糊的问题的回应。不幸的是,仍然没有进展;自从我发布以来我的发现:

  1. '调整'编译选项似乎没有帮助解决此问题。
  2. 从“空白”VB6项目添加对启用nlog的C ++组件的引用不会导致崩溃或导致奇怪的构建问题。所以它不是'本机'VB6问题,可能是nlog与其他引用组件使用的各种组件和第三方库之间的交互问题?
  3. 至于C ++调用约定:启用nlog的C ++组件 - 据我所知 - 符合这些约定,并且在VB6引用时确实工作正常,只要它不进行任何nlog API调用。不确定nlogc.DLL本身是否符合VB6,但我认为这是无关紧要的,因为API调用是从C ++组件进行的; VB6不应该知道或关心C ++组件引用的内容(就我对此的理解而言......)
  4. edit2:我还应该注意,在构建期间获得的错误消息是:“加载期间的错误。有关详细信息,请参阅”xxx“。当我调出日志文件时,其中的所有内容都是:“无法加载控件xxx”。有趣的是,如果我再次尝试构建,那么对该特定控件的所有引用都会从该特定项目中消失,从而导致编译错误。

6 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

我会尝试调整项目属性菜单,编译面板中的一些编译选项看看他们是否会对出现的问题产生任何额外的暗示。

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

答案 2 :(得分:0)

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

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

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

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

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

    更有可能的问题是NLog,或者你是如何通过代码调用它的,而不是VB6编译过程中出现问题。

答案 3 :(得分:0)

如果您认为它可能是链接器问题,那么它应该以相同的方式崩溃:

  1. 创建一个新的标准项目(任何类型)
  2. 添加新模块并将“declare”-statements复制到其中
  3. 编译
  4. 如果它没有崩溃,那就是别的了。

答案 4 :(得分:0)

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

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

MSDN Article on Calling convention.

答案 5 :(得分:0)

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