无法在 BPL 中找到未解析的外部/过程入口点
Unresolved external / procedure entry point could not be located in BPL
我在一个继承自 TFileStream 的现有项目中有一个名为 TTextStream 的 class。
它有一组重载的 operator<< 和 operator>> 函数作为成员函数。
class PACKAGE TTextStream : public TFileStream
大多数建议反而说您应该为这些运算符编写外部函数,并让他们成为所讨论的 class 的朋友,以便能够访问私有和受保护的成员。
因此,作为检查和清理代码的一部分,我这样做了。
并添加了函数示例
TTextStream& __fastcall operator >>(TTextStream& ts, AnsiString& s);
然后像往常一样在 .cpp 中执行。
然后在 TTextStream class 我添加了
friend TTextStream& __fastcall operator >>(TTextStream& ts, AnsiString& s);
该项目生成了一个 C++ Builder 程序包 (BPL),我们称它为 Foo.bpl。它编译得很好,然后我继续编译下一个 BPL 包,Bar.bpl,它使用来自 Foo.bpl 的功能.
所有这些 BPL 都输出到 "default" 文件夹,C:\Users\Public\Documents\Embarcadero\Studio。0\BLP
Foo.bpi 添加在 Requires 下 Bar.bpl 项目。
构建后我得到了
[ilink32 Error] Error: Unresolved external '__fastcall operator >>(TTextStream&, System::AnsiStringT<0>&)' referenced from BLABLABLA.OBJ
如果我尝试使用 Foo.lib 静态地 link,它工作正常。经过一番挖掘后,我得出的结论是函数没有正确导出到 Foo.bpl.
据我所知,我必须为此使用 PACKAGE 宏,所以我将其添加到 .h 文件的定义中以及 .cpp 文件中的实现。
PACKAGE TTextStream& __fastcall operator <<(TTextStream& ts, const AnsiString& s);
我重新编译 Foo.bpl,然后我编译 Bar.bpl 现在编译 link 很好。但是 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.0\BPL\Dcl\Bar.bpl
所以好像是抱怨没有找到一个函数,那个好像是在Foo.bpl中导出在Bar.bpl[=中93=]?
不太确定我错过了什么。 TDUMP 似乎显示它实际上正在导出。
C:\Users\Public\Documents\Embarcadero\Studio.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='@$xpTTextStream'
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 文件中实现。编译并 linkk BPL。
然后我创建了一个控制台应用程序,需要有问题的 bpl,包含带有函数定义的头文件 (functions.h),编译但失败 linking 出现同样的错误。所以我可能遗漏了一些明显的小东西...
所有这些都是使用 RAD Studio 10.3.2 和 not 使用 classic 编译器。
经过运行我进了这几次终于找到了一个好像"fix"的方法吧。
几个 BPL 项目,其中一些包含 IDE 组件,当我更改名称空间或其他内容时,拒绝安装并显示 "procedure entry point" 消息。函数已正确导出到 BPL,最终使其能够安装新版本组件 BPL 的是
- 从 IDE
中卸载组件
- 构建 BPL 项目
在此之后安装出现错误,改为
- 关闭 IDE
- 开始 IDE 备份
- 再次加载项目
- 安装组件
我不知道为什么会这样,但现在它在 5 个项目中都运行良好。我猜某些缓存或其他东西对我来说很糟糕。或者可能首先卸载的旧 BPL 实际上并没有完全删除。
如果有人知道发生了什么,我很乐意提供信息。
我在一个继承自 TFileStream 的现有项目中有一个名为 TTextStream 的 class。 它有一组重载的 operator<< 和 operator>> 函数作为成员函数。
class PACKAGE TTextStream : public TFileStream
大多数建议反而说您应该为这些运算符编写外部函数,并让他们成为所讨论的 class 的朋友,以便能够访问私有和受保护的成员。
因此,作为检查和清理代码的一部分,我这样做了。
并添加了函数示例
TTextStream& __fastcall operator >>(TTextStream& ts, AnsiString& s);
然后像往常一样在 .cpp 中执行。
然后在 TTextStream class 我添加了
friend TTextStream& __fastcall operator >>(TTextStream& ts, AnsiString& s);
该项目生成了一个 C++ Builder 程序包 (BPL),我们称它为 Foo.bpl。它编译得很好,然后我继续编译下一个 BPL 包,Bar.bpl,它使用来自 Foo.bpl 的功能.
所有这些 BPL 都输出到 "default" 文件夹,C:\Users\Public\Documents\Embarcadero\Studio。0\BLP
Foo.bpi 添加在 Requires 下 Bar.bpl 项目。
构建后我得到了
[ilink32 Error] Error: Unresolved external '__fastcall operator >>(TTextStream&, System::AnsiStringT<0>&)' referenced from BLABLABLA.OBJ
如果我尝试使用 Foo.lib 静态地 link,它工作正常。经过一番挖掘后,我得出的结论是函数没有正确导出到 Foo.bpl.
据我所知,我必须为此使用 PACKAGE 宏,所以我将其添加到 .h 文件的定义中以及 .cpp 文件中的实现。
PACKAGE TTextStream& __fastcall operator <<(TTextStream& ts, const AnsiString& s);
我重新编译 Foo.bpl,然后我编译 Bar.bpl 现在编译 link 很好。但是 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.0\BPL\Dcl\Bar.bpl
所以好像是抱怨没有找到一个函数,那个好像是在Foo.bpl中导出在Bar.bpl[=中93=]?
不太确定我错过了什么。 TDUMP 似乎显示它实际上正在导出。
C:\Users\Public\Documents\Embarcadero\Studio.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='@$xpTTextStream'
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 文件中实现。编译并 linkk BPL。
然后我创建了一个控制台应用程序,需要有问题的 bpl,包含带有函数定义的头文件 (functions.h),编译但失败 linking 出现同样的错误。所以我可能遗漏了一些明显的小东西...
所有这些都是使用 RAD Studio 10.3.2 和 not 使用 classic 编译器。
经过运行我进了这几次终于找到了一个好像"fix"的方法吧。 几个 BPL 项目,其中一些包含 IDE 组件,当我更改名称空间或其他内容时,拒绝安装并显示 "procedure entry point" 消息。函数已正确导出到 BPL,最终使其能够安装新版本组件 BPL 的是
- 从 IDE 中卸载组件
- 构建 BPL 项目
在此之后安装出现错误,改为
- 关闭 IDE
- 开始 IDE 备份
- 再次加载项目
- 安装组件
我不知道为什么会这样,但现在它在 5 个项目中都运行良好。我猜某些缓存或其他东西对我来说很糟糕。或者可能首先卸载的旧 BPL 实际上并没有完全删除。
如果有人知道发生了什么,我很乐意提供信息。