123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- {
- Objective-C rtl Test application by dmitry boyarintsev
- Should compile and run with no problems
- program output should look like:
- Objective-C runtime initialized successfuly
- -init method
- called newMethod1
- called newMethod2, a = 5; b = 4
- get double = 1.33300000000000E+000
- get float = 3.12500000000000E+000
- test successfully complete
- }
- program objcrtltest;
- {$mode objfpc}{$H+}
- uses
- objcrtl20, objcrtl10, objcrtl, objcrtlutils;
- {.$linkframework AppKit}
- {$linkframework Foundation}
- type
- TSubStructure = packed record
- a,b,c,d: byte;
- end;
- PSmallRecord = ^TSmallRecord;
- TSmallRecord = packed record
- a,b,c: byte;
- //d : Integer;
- d: byte;
- sub: TSubStructure;
- end;
- const
- newClassName = 'NSMyObject';
- overrideMethod = 'init';
- overrideMethodEnc = '@@:';
- newMethod1 = 'newMethod1';
- newMethod1Enc = 'v@:';
- newMethod2 = 'newMethod2::';
- newMethod2Enc = 'v@:ii';
- newMethod3 = 'getDouble';
- newMethod3Enc = 'd@:';
- newMethod4 = 'getFloat';
- newMethod4Enc = 'f@:';
- newMethod5 = 'getSmallRecord';
- newMethod5Enc = '{TSmallRecord=cccc{TSubStructure=cccc}}@:';
- varName = 'myvar';
- function imp_init(self: id; _cmd: SEL): id; cdecl;
- var
- sp : objc_super;
- begin
- writeln('-init method');
- sp := super(self);
- Result := objc_msgSendSuper(@sp, selector(overrideMethod), []);
- end;
- procedure imp_newMethod1(self: id; _cmd: SEL); cdecl;
- begin
- writeln('called newMethod1');
- end;
- procedure imp_newMethod2(self: id; _cmd: SEL; a, b: Integer); cdecl;
- begin
- writeln('called newMethod2, a = ', a, '; b = ', b);
- end;
- function imp_newMethod3(self: id; _cmd: SEL): Double; cdecl;
- begin
- Result := 1.333;
- end;
- function imp_newMethod4(self: id; _cmd: SEL): Single; cdecl;
- begin
- Result := 3.125;
- end;
- function imp_getSmallRec(seld: id; _cmd: SEL): TSmallRecord; cdecl;
- begin
- Result.a := 121;
- Result.b := 68;
- Result.c := 22;
- Result.d := 5;
- end;
- procedure RegisterSubclass(NewClassName: PAnsiChar);
- var
- cl : _Class;
- b : Boolean;
- begin
- cl := objc_allocateClassPair(objc_getClass('NSObject'), NewClassName, 0);
- b := class_addMethod(cl, selector(OverrideMethod), @imp_init, overrideMethodEnc) and
- class_addMethod(cl, selector(newMethod1), @imp_newMethod1, newMethod1Enc) and
- class_addMethod(cl, selector(newMethod2), @imp_newMethod2, newMethod2Enc) and
- class_addMethod(cl, selector(newMethod3), @imp_newMethod3, newMethod3Enc) and
- class_addMethod(cl, selector(newMethod4), @imp_newMethod4, newMethod4Enc) and
- class_addMethod(cl, selector(newMethod5), @imp_getSmallRec, newMethod5Enc);
- if not b then
- writeln('failed to add/override some method(s)');
- if not class_addIvar(cl, varName, sizeof(TObject), 1, _C_PASOBJ) then
- writeln('failed to add variable ', varName);
- objc_registerClassPair(cl);
- end;
- var
- obj : id;
- objvar : Ivar;
- stret : TSmallRecord;
- varobj : TObject;
- {$WARNINGS OFF} // cdecl'ared functions have no high parameter
- type
- TgetSmallRecord = function (obj: id; cmd: Sel; arg: array of const): TSmallRecord; cdecl;
- {$WARNINGS ON}
- begin
- // if InitializeObjcRtl20(DefaultObjCLibName) then // should be used of OSX 10.5 and iPhoneOS
- if InitializeObjcRtl10(DefaultObjCLibName) then // should be used of OSX 10.4 and lower
- writeln('Objective-C runtime initialized successfuly')
- else begin
- writeln('failed to initialize Objective-C runtime');
- Halt;
- end;
- RegisterSubclass(newClassName);
- writeln('registered');
- obj := AllocAndInit(newClassName);
- {obj := alloc(newClassName);
- objc_msgSend(obj, selector(overrideMethod), []);}
- writeln('sizeof(TSmallRecord) = ', sizeof(TSmallRecord));
- // this must be resolved at code-time (or compiler-time), not run-time
- {$WARNINGS OFF} // unreachable code
- if sizeof(TSmallRecord) in [1,2,4,8] then
- stret := TgetSmallRecord(objc_msgSend_stretreg)(obj, selector(newMethod5), [])
- else
- stret := TgetSmallRecord(objc_msgSend_stret)(obj, selector(newMethod5), []);
- {$WARNINGS ON}
- //writeln('p = ', Integer(p));
- //stret :=
- writeln('stret.a = ', stret.a);
- writeln('stret.b = ', stret.b);
- writeln('stret.c = ', stret.c);
- writeln('stret.d = ', stret.d);
- objc_msgSend(obj, selector(newMethod1), []);
- objc_msgSend(obj, selector(newMethod2), [5, 4]);
- writeln('get double = ', objc_msgSend_fpret(obj, selector(newMethod3), []));
- writeln('get float = ', objc_msgSend_fpret(obj, selector(newMethod4), []));
- objvar := class_getInstanceVariable( object_getClass(obj), varName);
- varobj := TObject.Create;
- writeln('var Value = ', Integer(object_getIvar(obj, objvar)));
- writeln('setting new Value = ', Integer(varobj));
- object_setIvar(obj, objvar, varobj);
- writeln('var Value = ', Integer(object_getIvar(obj, objvar)));
- writeln('var offset = ', Integer(ivar_getOffset(objvar)));
- writeln('var name = ', ivar_getName(objvar));
- writeln('var type = ', ivar_getTypeEncoding(objvar));
- release(obj);
- varobj.Free;
- writeln('test successfully complete');
- end.
|