【发布时间】:2011-02-13 04:41:53
【问题描述】:
我正在尝试重新配置我的应用程序以大量使用包。在使用几个不同的包进行链接时,我和另一个运行类似实验的开发人员都遇到了一些麻烦。我们可能都做错了什么,但天知道是什么:)
情况是这样的:
- 第一个包
PackageA.bpl包含C++ 类FooA。该类使用PACKAGE指令声明。 第二个包
PackageB.bpl包含一个继承自FooA的类,称为FooB。它包括FooB.h,并且该包是使用运行时包构建的,并通过添加对PackageA.bpi的引用来链接到PackageA。-
在构建
PackageB时,它可以正常编译,但链接失败并出现许多未解决的外部问题,其中前几个是:[ILINK32 Error] Error: Unresolved external '__tpdsc__ FooA' referenced from C:\blah\FooB.OBJ[ILINK32 Error] Error: Unresolved external 'FooA::' referenced from C:\blah\FooB.OBJ[ILINK32 Error] Error: Unresolved external '__fastcall FooA::~FooA()' referenced from blah\FooB.OBJ
等等
在PackageA.bpl 上运行 TDump 显示:
Exports from PackageA.bpl
14 exported name(s), 14 export addresse(s). Ordinal base is 1.
Sorted by Name:
RVA Ord. Hint Name
-------- ---- ---- ----
00002A0C 8 0000 __tpdsc__ FooA
00002AD8 10 0001 __linkproc__ FooA::Finalize
00002AC8 9 0002 __linkproc__ FooA::Initialize
00002E4C 12 0003 __linkproc__ PackageA::Finalize
00002E3C 11 0004 __linkproc__ PackageA::Initialize
00006510 14 0007 FooA::
00002860 5 0008 FooA::FooA(FooA&)
000027E4 4 0009 FooA::FooA()
00002770 3 000A __fastcall FooA::~FooA()
000028DC 6 000B __fastcall FooA::Method1() const
000028F4 7 000C __fastcall FooA::Method2() const
00001375 2 000D Finalize
00001368 1 000E Initialize
0000610C 13 000F ___CPPdebugHook
因此,该类肯定似乎已导出并可用于链接。我可以看到 ILink32 说它正在寻找和未找到的特定内容的条目。在 BPI 文件上运行 TDump 会显示类似的条目。
其他信息
该类确实是 TObject 的后代,尽管最初在重构为包之前它是一个普通的 C++ 类。 (下面有更多详细信息。无论如何,在尝试用非常像 Delphi 的东西来解决问题时,使用 VCL 样式的类似乎“更安全”。改变它只会改变未解决的外部的顺序,首先找不到 Method1 和 @987654337 @,然后是其他人。)
FooA的声明:
class PACKAGE FooA: public TObject {
public:
FooA();
virtual __fastcall ~FooA();
FooA(const FooA&);
virtual __fastcall long Method1() const;
virtual __fastcall long Method2() const;
};
和FooB:
class FooB: public FooA {
public:
FooB();
virtual __fastcall ~FooB();
... other methods...
};
所有方法肯定都在 .cpp 文件中实现,所以不是因为它们不存在而找不到它们! .cpp 文件还包含靠近顶部的 #pragma package(smart_init),位于 include 之下。
可能有帮助的问题...
- 使用 C++ 的包是否可靠,还是只能用于 Delphi 代码?
- 通过添加对它的 BPI 的引用来链接到第一个包是否正确 - 你应该这样做吗?我可以使用 LIB,但它似乎使第二个包更大,我怀疑它在第一个包的内容中静态链接。
- 我们能否仅在
TObject派生类上使用PACKAGE指令?在标准 C++ 类上使用它没有编译器警告。 - 将代码拆分成包是实现代码隔离和通过定义的层/接口进行通信的最佳方式吗?我一直在研究这条路径,因为它似乎是 C++Builder / Delphi 方式,如果它有效,它看起来很有吸引力。但是有更好的选择吗?
- 我对使用包非常陌生,之前只通过使用组件了解它们。任何一般性的建议都会很棒!
我们使用的是 C++Builder 2010。我在上面的代码示例中捏造了类和方法名称,但除此之外的细节正是我们所看到的。
【问题讨论】:
标签: delphi linker package c++builder