【发布时间】:2021-04-05 22:50:51
【问题描述】:
我的情况有点复杂,所以我会尽量详细解释一下,以便一切都清楚。对不起,如果帖子有点大,但我认为这是解决它的最佳方式。感谢您的耐心等待。
问题
我正在开发一个 Qt 4.8.4 项目,在该项目中我需要使用提供的闭源 dll,我们称之为 original.dll,并且必须使用 MinGW 4.4 进行编译。 0 32 位。起初,我虽然可以简单地使用 dumpcpp 来生成必要的标头并直接使用 original.cpp 和 original.h。这里的主要问题是 dll 在设计时考虑到了 C#,并且它使用了 original.h 上不存在的一些事件,因此以这种方式无法使用。
我想到了编写一个 C# 包装器来管理所有内容,用对象方法替换这些事件,然后,一旦生成 wrapper.dll,就使用 dumpcpp 使用此包装器,并覆盖那些被设置为事件的对象方法。我创建了包装器,构建了 x86 COM dll 并使用 dumpcpp 来获取 wrapper.cpp 和 wrapper.h,并添加了这两个文件,以及项目的两个 dll。现在的主要问题是,每当我尝试创建包装器上定义的类的实例时,我无法构建项目,它总是失败并显示消息 collect2: ld returned 5 exit status强>。
项目配置
在 .pro 文件中,我已将 axcontainer 添加到 QT 模块中。
original.dll 和 wrapper.dll 位于 project_path/sdk/lib,而 wrapper.cpp 和 wrapper.h 位于 project_path/sdk/inc。
为了将它们添加到项目中,我在 .pro 中添加了以下几行
INCLUDEPATH += $$PWD/sdk/inc
LIBS += -L$$PWD/sdk/lib -loriginal -lwrapper
我尝试过的
我一直在寻找这个错误,但它完全没有记录,而且我尝试过的结果 (this, for example) 也没有成功。
我最终决定修改 Qmake 在项目上创建的 Makefile.Release 文件,为链接器添加一些标志并获取更多信息。添加到链接器的整个标志集是-Wl,-s -mthreads -shared -Wl,--out-implib,c:\Users\javie\Desktop\lib.a -Wl,--verbose --dll-verbose -Wl,--no-gc-sections(--no-gc-sections 没有区别)。
我发现,一旦链接器找到库,它就会立即崩溃,如下图所示(我不得不覆盖部分目录以保留一些个人信息,抱歉):
我首先指定哪个 dll 并不重要,即使我删除了两个 -l 标志中的任何一个,它总是会以这种方式崩溃。
如果我删除这两个 dll,我在使用 wrapper.h 中指定的类的文件上会遇到很多错误,例如:
在这种情况下,结果是collect2: ld returned 1 exit status
我不知道我还能尝试什么,甚至不知道为什么会发生这种情况。 dll应该是动态链接库,那么为什么ld无法静态链接它们呢?你们中有人知道任何其他可能的解决方法吗?有人可以帮我吗?这是一个重要的项目,我完全陷入了困境。
非常感谢!
【问题讨论】:
-
如果不起作用(虚拟 DLL 链接失败),我会尝试按照本文调用虚拟 DLL:Calling Managed .NET C# COM Objects from Unmanaged C++ Code 在 Visual C++ 项目中
-
好的,所以在您发布@bartolo-otrit 的链接中,我需要将.tlb 文件添加到项目中,而不是dll?我对吗?我应该在 .pro 文件的哪个部分添加 tlb 文件?非常感谢!
-
根据Importing Type Libraries,类型库允许您在不知道其位置的情况下使用 COM 对象,因此看起来 COM DLL 不应直接链接到您的项目,因为它们已在系统。我没有 Windows 机器来检查这些假设。
-
我一般不会使用 COM 在 .NET 和 Qt 项目之间进行通信。看起来某种形式的 IPC 或 RPC 更好。
-
看来我无法使用@bartolo-otrit 发布的响应,因为在 Qt 项目上导入 tlb 时出现很多错误。如果我使用 VS C++ 项目,它可以完美运行。可能是因为我需要使用 MinGW 而不是 VS 编译器吗?我需要使用 COM,因为它是原始 dll 的编写方式