Haruyuki Mohri

毛利春幸のブログです。

BCC32で TFuncにデータを渡す場合

When dealing with TFunc in BCC32(C++Builder 10.2).

For example, suppose Delphi side has the following function.

type
  Tproc_func = record
    {When TFunc is an argument as shown below. }
    function func1(func: TFunc<Integer, String>):String;
  end;
implementation
function Tproc_func.func1(func: TFunc<Integer, String>): String;
begin
  Result  := func(CurrentYear);
end;

The func1 function has an argument of TFunc.
In this case, Delphi can handle it very simply.

function test_func: String;
begin
  {Anonymous Method are available.}
  Result  :=  func1(function (i: Integer): String begin end);
end;

Since bcc64 or bcc32c is based on C++11, lambda can be used.
But, when you use it from BCC32, preparation is a little needed.

You need a class that inherits from TCppInterfacedObject<TFunc__2<T1,T2> >.
And we need the Invoke() function inside the class.

#include <sstream>
template<typename T1, typename T2>
struct T_func1 : TCppInterfacedObject<TFunc__2<T1,T2> >
{
    String __fastcall to_string(int i)
    {
        std::stringstream lss;
        lss << i;
        return lss.str().c_str();
    }
    T2 __fastcall Invoke(T1 i)
    {
        //Write the code you want to pass to TFunc__2 here.
        return static_cast<T2>("Delphi was released in " + to_string(i - 22) + " for the first edition.");
    }
};

Pass the above class instance to TFunc<Integer, String>.

__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner)
{
    Tproc_func lfunc;
    Label1->Caption = lfunc.func1(new T_func1<int, String>());
}

We were able to pass the TFunc even BCC32 in the manner described above.

f:id:mojeld:20170914142802p:plain