使用C ++ Builder包时如何解决未解析的外部问题?

时间:2010-04-28 05:19:18

标签: delphi linker package c++builder

我正在尝试重新配置我的应用程序以大量使用软件包。我和另一个运行类似实验的开发人员在使用多个不同的包进行链接时遇到了一些麻烦。我们可能都做错了什么,但善良知道什么:)

情况如下:

  • 第一个包PackageA.bpl包含C ++类FooA。该类使用PACKAGE指令声明。
  • 第二个包PackageB.bpl包含一个继承自FooA的类,名为FooB。它包含FooB.h,包使用运行时包构建,并通过添加对PackageA的引用链接到PackageA.bpi

  • 构建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 ++类。 (更详细的说明。使用VCL风格的类似乎“更安全”,试图用这样的Delphi-ish之类的东西来解决问题。改变它只会改变未解析的外部的顺序,首先找不到Method1Method2,然后是其他人。)

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文件还在include附近的顶部附近包含#pragma package(smart_init)

可能有帮助的问题......

  • 使用C ++的包是可靠的,还是只能用于Delphi代码?
  • 通过添加对其BPI的引用正确链接到第一个包 - 您应该如何做到这一点?我可以使用LIB,但它似乎使第二个包更大,我怀疑它是第一个内容的静态链接。
  • 我们是否可以仅在PACKAGE派生类上使用TObject指令?在标准C ++类上没有使用它的编译器警告。
  • 将代码拆分成包是实现隔离代码和通过定义的层/接口进行通信的最佳方法吗?我一直在调查这条路径,因为它似乎是C ++ Builder / Delphi方式,如果它起作用,它看起来很有吸引力。但是有更好的选择吗?
  • 我很擅长使用软件包,并且之前只使用过组件才知道它们。任何一般性的建议都会很棒!

我们正在使用C ++ Builder 2010.我在上面的代码示例中编写了类和方法名称,但除此之外,细节正是我们所看到的。

3 个答案:

答案 0 :(得分:9)

答案 1 :(得分:2)

也许是个愚蠢的问题,但你的BPI / BPL文件是否在链接器找到正确的路径? 我在BCB5中创建了一个使用了几个链接包的应用程序,但是不记得是否有任何特殊的东西。

答案 2 :(得分:1)

对于我来说,cpp文件中的 #pragma package(smart_init,weak)解决了这个问题。另见http://flylib.com/books/en/3.264.1.27/1/ cpp-> obj文件静态链接而不影响其他任何内容。