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的代码吗?

解决方案 »

  1.   

    我试了一下,确实有这个问题,应该不是库的问题,TBitmap的其他方法都可以调用
      

  2.   


    可以自己编译pas源代码代替系统的库吗?
      

  3.   

    可以,添加.pas到项目就可以
      

  4.   


    我的意思是编译成lib替换系统的lib。
      

  5.   


     我把FMX.Graphics.pas复制到工程目录,加入工程,编译还是链接错误,我再
    #include "FMX.Graphics.hpp" //该文件已生成,debug下也有obj和dcu文件
    再编译还是链接错误?
      

  6.   

    应该是CB编译器的一个BUG,我先看一下它的中间输出
      

  7.   

    可以确认是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再加入工程来解决。
      

  8.   


    为什么CB编译器会对这么个别的函数生成的函数名不一致呢?
    Delphi应该不存在这种问题?
      

  9.   

    所以才是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值
      

  10.   

    帮我看一下这个:
    https://bbs.csdn.net/topics/394828608