У меня есть класс с именем TTextStream в существующем проекте, который наследуется от TFileStream . Он имел набор перегруженных операторов << </strong> и операторов >> функций в качестве функций-членов.
class PACKAGE TTextStream : public TFileStream
В большинстве рекомендаций вместо этого говорится, что вы должны писать внешние функции дляэти операторы и сделайте их друзьями рассматриваемого класса, чтобы иметь доступ к частным и защищенным членам.
Так что, как часть прохождения и очистки кода, я сделал это.
И примердобавленной функции
TTextStream& __fastcall operator >>(TTextStream& ts, AnsiString& s);
Реализация затем в .cpp как обычно.
Затем в TTextStream добавленном классе
friend TTextStream& __fastcall operator >>(TTextStream& ts, AnsiString& s);
В проекте создается пакет C ++ Builder (BPL) , назовем его Foo.bpl . Он скомпилировался нормально, а затем я продолжил компилировать следующий пакет BPL, Bar.bpl , который использует функциональность из Foo.bpl .
Все эти BPL выданыв папку «по умолчанию» добавляется C: \ Users \ Public \ Documents \ Embarcadero \ Studio \ 20.0 \ BLP
Foo.bpi в Требуется в проекте Bar.bpl .
При сборке я получил
[ilink32 Error] Error: Unresolved external '__fastcall operator >>(TTextStream&, System::AnsiStringT<0>&)' referenced from BLABLABLA.OBJ
Если я попытался статически связать с Foo.lib вместо этого работает нормально. После некоторых копаний я прихожу к выводу, что функция не была правильно экспортирована в Foo.bpl .
Насколько я понимаю, я должен использовать ПАКЕТ макрос для этого, поэтому я добавляю это в определение в файле .h и реализацию в файле .cpp .
PACKAGE TTextStream& __fastcall operator <<(TTextStream& ts, const AnsiString& s);
Я перекомпилирую Foo.bpl , затем я компилирую Bar.bpl , и теперь он хорошо компилируется и связывается. Но Bar.bpl - это пакет времени выполнения и времени разработки, и когда я собираюсь установить его в IDE, появляется диалоговое окно с сообщением Windows, в основном с тем же сообщением, что и раньше.
The procedure entry point @$blsh$qr11TTextStreamrx27System@%AnsiStringT$us$i0$% could not be located in the dynamic library C:\Users\Public\Documents\Embarcadero\Studio\20.0\BPL\Dcl\Bar.bpl
Кажется, что он жалуется на то, что не может найти функцию, которая экспортируется в Foo.bpl в Bar.bpl ?
Не совсем уверен, что яотсутствует. TDUMP , кажется, показывает, что он на самом деле экспортируется.
C:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl>tdump -oiEXTDEF Foo.bpl | grep TTextStream
File STDIN:
00050668 211 0000 __fastcall operator <<(TTextStream&, const char *)
000505D8 210 0001 __fastcall operator <<(TTextStream&, System::WideString&)
0005057C 209 0002 __fastcall operator <<(TTextStream&, System::AnsiStringT<0>&)
00051350 213 0003 __fastcall operator >>(TTextStream&, System::WideString&)
000506B0 212 0004 __fastcall operator >>(TTextStream&, System::AnsiStringT<0>&)
00051D6C 218 0009 __tpdsc__ TTextStream
00051D3C 217 00DB TTextStream::
00051A18 216 00DC TTextStream::operator =(TTextStream&)
00050150 207 00DD __fastcall TTextStream::TTextStream(System::AnsiStringT<0>&, unsigned short, TEOLMode)
0005157C 215 00DE TTextStream::TTextStream(TTextStream&)
000514F4 214 00DF __fastcall TTextStream::~TTextStream()
0005051C 208 00E0 __fastcall TTextStream::WriteEOL()
или без устранения неполадок
EXPORT ord:0211='@$blsh$qr11TTextStreampxc'
EXPORT ord:0210='@$blsh$qr11TTextStreamrx17System@WideString'
EXPORT ord:0209='@$blsh$qr11TTextStreamrx27System@%AnsiStringT$us$i0$%'
EXPORT ord:0213='@$brsh$qr11TTextStreamr17System@WideString'
EXPORT ord:0212='@$brsh$qr11TTextStreamr27System@%AnsiStringT$us$i0$%'
EXPORT ord:0218='@$xp$11TTextStream'
EXPORT ord:0050='@TLangFormNode@SaveToASCII$qqrp11TTextStreamui'
EXPORT ord:0217='@TTextStream@'
EXPORT ord:0216='@TTextStream@$basg$qrx11TTextStream'
EXPORT ord:0207='@TTextStream@$bctr$qqrrx27System@%AnsiStringT$us$i0$%us8TEOLMode'
EXPORT ord:0215='@TTextStream@$bctr$qrx11TTextStream'
EXPORT ord:0214='@TTextStream@$bdtr$qqrv'
EXPORT ord:0208='@TTextStream@WriteEOL$qqrv'
Я также протестировал другие соглашения о вызовах, чтобы исключить это.
В качестве вторичного теста я также создал небольшой тестовый пример.
Проект, производящий bpl с модулем (functions.h / functions.cpp), добавленным сединственная функция
#ifndef __MYFUNCS__
#define __MYFUNCS__
#pragma package(smart_init)
PACKAGE int add(int a, int b)
#endif
, которая просто складывает два числа вместе с реализацией в файле .cpp. Скомпилируйте и скомпонуйте BPL.
Затем я создал консольное приложение, которое требовало рассматриваемого bpl, включило заголовочный файл с определением функции (functions.h), скомпилировало и не установило связьс той же ошибкой. Так что я, вероятно, упускаю некоторые незначительные очевидные вещи ...
Все это делается с использованием RAD Studio 10.3.2 и , а не с использованием classic компилятор.