Как решить неразрешенную внешнюю проблему при использовании пакетов 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
и т.п.
Запуск TDump наPackageA.bpl
показывает:
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 говорит, что ищет и не находит. Запуск TDump в файле BPI показывает похожие записи.
Другая информацияКласс происходит от TObject, хотя изначально до рефакторинга в пакеты это был обычный класс C ++. (Более подробно ниже. Кажется, «безопаснее» использовать классы в стиле VCL при попытке решить проблемы с очень Delphi-ишной штукой, подобной этой. В любом случае, изменение этого параметра только изменяет порядок неразрешенных внешних объектов, чтобы сначала не найтиMethod1
а такжеMethod2
потом другие.)
Декларация для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)
около вершины, под включает.
PACKAGE
директива только наTObject
классы? Нет никакого предупреждения компилятора, использующего это на стандартных классах C ++.Является ли разбиение кода на пакеты лучшим способом для достижения цели изоляции кода и обмена данными через определенные уровни / интерфейсы? Я изучал этот путь, потому что он, похоже, C ++ Builder / Delphi Way, и если он работал, он выглядит привлекательно. Но есть ли лучшие альтернативы?Я очень новичок в использовании пакетов и раньше знал о них только через компоненты. Любые общие слова совета будут великолепны!Мы используем C ++ Builder 2010. Я сфабриковал имена классов и методов в приведенных выше примерах кода, но кроме этого детали именно то, что мы видим.