Неразрешенная внешняя / процедурная точка входа не может быть расположена в BPL - PullRequest
1 голос
/ 09 октября 2019

У меня есть класс с именем 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 компилятор.

1 Ответ

0 голосов
/ 18 октября 2019

После нескольких попыток я, наконец, нашел способ, который, кажется, "исправил" это. Несколько проектов BPL, некоторые из которых содержат компоненты IDE, отказывались устанавливать с сообщением «точка входа в процедуру», когда я, например, изменил пространство имен или что-то в этом роде. Функции были правильно экспортированы в BPL, и, наконец, он смог установить новую версию компонента BPL:

  • Удаление компонента из IDE
  • Сборка проекта BPL

Установка после этого выдавала ошибку, вместо

  • Завершение работы IDE
  • Запуск резервного копирования IDE
  • Загрузка проекта снова
  • Установить компонент

Понятия не имею, почему это работает, но теперь оно отлично работает для 5 проектов. Я предполагаю, что какой-то кеш или что-то испортилось для меня. Или, может быть, старый BPL, который был удален первым, на самом деле не удаляется полностью.

Если у кого-то есть идеи, что происходит, я был бы рад за информацию.

...