Fmx::Graphics::TBitmap::ApplyMask函数二进制代码在哪个库里?为啥默认无法链接?

ooolinux 2019-10-16 02:59:53
Fmx::Graphics::TBitmap::ApplyMask函数二进制代码在哪个库里?为啥默认无法链接?
void __fastcall TForm1::Button2Click(TObject *Sender)
{
TByteArray *ba;
ba=bmp->CreateMask();
Image1->Bitmap->Clear(claBlue);
Image1->Bitmap->ApplyMask(ba);
}
链接出错:
[ilink32 Error] Error: Unresolved external '__fastcall Fmx::Graphics::TBitmap::ApplyMask(System::StaticArray<unsigned char, 32768> * const, const int, const int)' referenced from D:\BCB PROJECTS\BITMAPDEMO\WIN32\DEBUG\UNIT1.OBJ
能手工往系统的库里添加ApplyMask的代码吗?
...全文
329 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
ooolinux 2019-10-25
  • 打赏
  • 举报
回复
引用 16 楼 早打大打打核战争 的回复:
可以用社区版测试一下


暂时懒得安装了,要搞虚拟机也麻烦。
  • 打赏
  • 举报
回复
可以用社区版测试一下
ooolinux 2019-10-24
  • 打赏
  • 举报
回复
引用 14 楼 早打大打打核战争 的回复:
[quote=引用 12 楼 ooolinux 的回复:] 我的意思是,这个方法是普通的方法,里面的参数类型也不是前所未有的,为什么编译器独独对这个方法的名字修饰有问题?
也可能还有其他方法有问题,只是还没人碰到~~~ [/quote] 这种问题还是相当罕见的,也不排除外部原因。
  • 打赏
  • 举报
回复
引用 12 楼 ooolinux 的回复:
[quote=引用 11 楼 早打大打打核战争 的回复:]
所以才是BUG呀,一致了就没问题了。应该是编译器解析.hpp里的声明,生成唯一的符号名(一般称之为名字破坏name mangling)的问题。Delphi也可能有这种问题
对于DLL,Delphi不使用name mangling,而是直接导出C符号,但是对于.lib/.obj、.bpl,Delphi使用和CB兼容的name mangling,64位编译器使用clang/llvm兼容的name mangling,而32位编译器使用传统Borland C++的name mangling,对于.dcu,则使用另一套方法,似乎是给每个符号生成了唯一的hash值


我的意思是,这个方法是普通的方法,里面的参数类型也不是前所未有的,为什么编译器独独对这个方法的名字修饰有问题?[/quote]

也可能还有其他方法有问题,只是还没人碰到~~~
ooolinux 2019-10-24
  • 打赏
  • 举报
回复
帮我看一下这个:
https://bbs.csdn.net/topics/394828608
ooolinux 2019-10-24
  • 打赏
  • 举报
回复
引用 11 楼 早打大打打核战争 的回复:
所以才是BUG呀,一致了就没问题了。应该是编译器解析.hpp里的声明,生成唯一的符号名(一般称之为名字破坏name mangling)的问题。Delphi也可能有这种问题
对于DLL,Delphi不使用name mangling,而是直接导出C符号,但是对于.lib/.obj、.bpl,Delphi使用和CB兼容的name mangling,64位编译器使用clang/llvm兼容的name mangling,而32位编译器使用传统Borland C++的name mangling,对于.dcu,则使用另一套方法,似乎是给每个符号生成了唯一的hash值


我的意思是,这个方法是普通的方法,里面的参数类型也不是前所未有的,为什么编译器独独对这个方法的名字修饰有问题?
  • 打赏
  • 举报
回复
所以才是BUG呀,一致了就没问题了。应该是编译器解析.hpp里的声明,生成唯一的符号名(一般称之为名字破坏name mangling)的问题。Delphi也可能有这种问题
对于DLL,Delphi不使用name mangling,而是直接导出C符号,但是对于.lib/.obj、.bpl,Delphi使用和CB兼容的name mangling,64位编译器使用clang/llvm兼容的name mangling,而32位编译器使用传统Borland C++的name mangling,对于.dcu,则使用另一套方法,似乎是给每个符号生成了唯一的hash值
  • 打赏
  • 举报
回复
可以确认是CB编译器的一个BUG,原因是CB编译器为TBitmap::ApplyMask生成的函数名(C++名)和Delphi编译器生成的C++名不一致,CB win64编译器生成的是
_ZN3Fmx8Graphics7TBitmap9ApplyMaskEPN6System11StaticArrayIhLi32768EEEii
而Delphi win64编译器生成的是_ZN3Fmx8Graphics7TBitmap9ApplyMaskEPKN6System11StaticArrayIhLi32768EEEii
这样链接时找不到对应的符号,就报错了
用c++filt工具查看,Delphi编译器生成的函数原型是:
Fmx::Graphics::TBitmap::ApplyMask(System::StaticArray<unsigned char, 32768> const*, int, int)
这个是对的,Mask参数有const修饰
而CB 编译器生成的函数原型是:
Fmx::Graphics::TBitmap::ApplyMask(System::StaticArray<unsigned char, 32768>*, int, int)

所以,解决方法也很简单,在程序中替换一下对应的C++名就可以了:
#if defined(_WIN64)
#pragma alias "_ZN3Fmx8Graphics7TBitmap9ApplyMaskEPN6System11StaticArrayIhLi32768EEEii" = "_ZN3Fmx8Graphics7TBitmap9ApplyMaskEPKN6System11StaticArrayIhLi32768EEEii"
#elif defined(__WIN32__)
#pragma alias "@Fmx@Graphics@TBitmap@ApplyMask$qqrxp32System@%StaticArray$uci$i32768$%xixi" = "@Fmx@Graphics@TBitmap@ApplyMask$qqrpx32System@%StaticArray$uci$i32768$%xixi"
#endif

这个方法对于CB win64和win32传统编译器都有效,但是对于基于clang的win32编译器(bcc32c)无效,还没有找到原因,虽然查看两个编译器生成的obj中ApplyMask的C++名是一样的。只能修改fmx.graphics.obj再加入工程来解决。
ooolinux 2019-10-23
  • 打赏
  • 举报
回复
引用 9 楼 早打大打打核战争 的回复:
可以确认是CB编译器的一个BUG,原因是CB编译器为TBitmap::ApplyMask生成的函数名(C++名)和Delphi编译器生成的C++名不一致,CB win64编译器生成的是 _ZN3Fmx8Graphics7TBitmap9ApplyMaskEPN6System11StaticArrayIhLi32768EEEii 而Delphi win64编译器生成的是_ZN3Fmx8Graphics7TBitmap9ApplyMaskEPKN6System11StaticArrayIhLi32768EEEii 这样链接时找不到对应的符号,就报错了 用c++filt工具查看,Delphi编译器生成的函数原型是: Fmx::Graphics::TBitmap::ApplyMask(System::StaticArray<unsigned char, 32768> const*, int, int) 这个是对的,Mask参数有const修饰 而CB 编译器生成的函数原型是: Fmx::Graphics::TBitmap::ApplyMask(System::StaticArray<unsigned char, 32768>*, int, int) 所以,解决方法也很简单,在程序中替换一下对应的C++名就可以了: #if defined(_WIN64) #pragma alias "_ZN3Fmx8Graphics7TBitmap9ApplyMaskEPN6System11StaticArrayIhLi32768EEEii" = "_ZN3Fmx8Graphics7TBitmap9ApplyMaskEPKN6System11StaticArrayIhLi32768EEEii" #elif defined(__WIN32__) #pragma alias "@Fmx@Graphics@TBitmap@ApplyMask$qqrxp32System@%StaticArray$uci$i32768$%xixi" = "@Fmx@Graphics@TBitmap@ApplyMask$qqrpx32System@%StaticArray$uci$i32768$%xixi" #endif 这个方法对于CB win64和win32传统编译器都有效,但是对于基于clang的win32编译器(bcc32c)无效,还没有找到原因,虽然查看两个编译器生成的obj中ApplyMask的C++名是一样的。只能修改fmx.graphics.obj再加入工程来解决。
为什么CB编译器会对这么个别的函数生成的函数名不一致呢? Delphi应该不存在这种问题?
ooolinux 2019-10-22
  • 打赏
  • 举报
回复
引用 7 楼 早打大打打核战争 的回复:
应该是CB编译器的一个BUG,我先看一下它的中间输出
可以向英巴提交一下。
  • 打赏
  • 举报
回复
应该是CB编译器的一个BUG,我先看一下它的中间输出
ooolinux 2019-10-21
  • 打赏
  • 举报
回复
引用 5 楼 早打大打打核战争 的回复:
不用自己编译,会自动编译
我把FMX.Graphics.pas复制到工程目录,加入工程,编译还是链接错误,我再 #include "FMX.Graphics.hpp" //该文件已生成,debug下也有obj和dcu文件 再编译还是链接错误?
  • 打赏
  • 举报
回复
不用自己编译,会自动编译
ooolinux 2019-10-21
  • 打赏
  • 举报
回复
引用 3 楼 早打大打打核战争 的回复:
可以,添加.pas到项目就可以


我的意思是编译成lib替换系统的lib。
  • 打赏
  • 举报
回复
可以,添加.pas到项目就可以
ooolinux 2019-10-21
  • 打赏
  • 举报
回复
引用 1 楼 早打大打打核战争 的回复:
我试了一下,确实有这个问题,应该不是库的问题,TBitmap的其他方法都可以调用


可以自己编译pas源代码代替系统的库吗?
  • 打赏
  • 举报
回复
我试了一下,确实有这个问题,应该不是库的问题,TBitmap的其他方法都可以调用

828

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧