Haruyuki Mohri

毛利春幸のブログです。

Delphi(iOS) - 自作したObjective-Cのクラスとメソッドを呼び出す

Objective-Cで自作したCocoa Touch Static Library(*.a)を呼び出す

mojelder.hatenablog.com
前回Cocoa Touch Static Libraryの作り方を記載致しました。
作成した*.aファイルをDelphiから呼ぶ方法です。

1.Delphi Fire Monkeyの新規プロジェクトを作成

f:id:mojeld:20160104145529j:plain
TButton で自作したObjective-Cのクラスを呼び出します。
TEditを2つ入力とし、TLabelに結果を返すようにします。

2.nmコマンドで *.aファイルを呼び出す為の内容を確認

MacOSターミナル等のnmコマンドで*.aの内容を確認します。
f:id:mojeld:20160104150326j:plain

3.NSObjectを継承したinterfaceを作成

前回作成した*.aはlibMo201601Lib.aでクラス名がMo201601Libですのでそれを使います

  Mo201601Lib = interface(NSObject) ['{CFAA0BDC-4AB1-4FB4-B95D-5772A659F30E}']
    function Addr(i1, l2: Integer): Integer; cdecl;
    function HelloStr: NSString; cdecl;
  end;
  Mo201601LibClass = interface(NSObjectClass) ['{61D41F11-90E1-420E-8320-C4E15714B847}']
  end;

NSObjectClassは空のinterfaceでいいみたいです。

4.TOCGenericImport<>継承のクラスを作成する

TMo201601LibClass = class(TOCGenericImport<Mo201601LibClass, Mo201601Lib>) end;

TOCGenericImportには先ほどのinterfaceを入れます。

5.先ほどの3と4を足すと下記の感じです

uLib_iOSClass.pas

unit uLib_iOSClass;

interface
uses
  System.SysUtils, System.Types,
  System.TypInfo,
  Macapi.ObjectiveC,Macapi.ObjCRuntime,
  iOSapi.CocoaTypes,iOSapi.foundation; 

type
  Mo201601Lib = interface(NSObject) ['{CFAA0BDC-4AB1-4FB4-B95D-5772A659F30E}'] //Objective-Cで作成したクラス名
    function Addr(i1, l2: Integer): Integer; cdecl; //第2引数はラベル名にする必要があります。
    function HelloStr: NSString; cdecl;
  end;
  Mo201601LibClass = interface(NSObjectClass) ['{61D41F11-90E1-420E-8320-C4E15714B847}']
  end;
  TMo201601LibClass = class(TOCGenericImport<Mo201601LibClass, Mo201601Lib>) end;
{$O-}
//function Dummy1: Mo201601LibClass; cdecl; external 'libMo201601Lib.a' name '_OBJC_CLASS_$_Mo201601Lib';//これ要らないです。
{$O+}
function Seattle_FakeLoader ( val : integer ) : Integer; cdecl; external 'libMo201601Lib.a' name 'fakeLoader';
implementation
end.

6.プロジェクトフォームのボタンイベントで5を呼び出す

メインフォーム側ボタンのOnClickイベントでMo201601Libを呼び出します。

uses Macapi.Helpers;
procedure TForm1.Button1Click(Sender: TObject);
var
  obj:  Mo201601Lib; //変数はクラスinterfaceで作成します。
  i1, i2: Integer;
  iRez: Integer;
  stTemp: String;
begin
  obj := TMo201601LibClass.Create; //CreateはTOCGenericImportで作成したクラスを使います
  i1  := StrToIntDef(Edit1.Text, 1);
  i2  := StrToIntDef(Edit2.Text, 1);
  iRez  := obj.Addr(i1, i2); 
  stTemp  := NSStrToStr(obj.HelloStr);
  Label1.Text := IntToStr(iRez) + stTemp;
end;

元ネタ

community.embarcadero.com