[fpc-devel] RTTI interface & variant late binding issue (mORMot)
Steve Hildebrandt
Steve.Kassel at web.de
Mon Apr 13 14:21:56 CEST 2015
Am 13.04.2015 um 12:02 schrieb Steve Hildebrandt:
>
>
> Am 13.04.2015 um 09:38 schrieb Alfred:
>> Please do include me !
>> I have included the rtti-patch (diff) based on the current (today :
>> 30566) trunk.
>> Its nothing else than the patch-set from Steve, but with one change:
>> for k:=0 to def.paras.count-1 do
>> begin
>> para:=tparavarsym(def.paras[k]);
>> {note from Alf:}
>> {this was in the first patch set by Steve}
>> {left out by Steve in the current patch}
>> {?}
>> {
>> if (vo_is_hidden_para in para.varoptions) and not
>> (vo_is_self in para.varoptions) then
>> continue;
>> }
>> Thanks, Alf.
> This was made, when I started actually using the generated RTTI.
> It was kind of problematic to invoke a method, if you have no
> information how to pass the self parameter along.
>
> mfg Steve
I think something got mixed up here.
I got confused and didn't look into things properly, sorry.
The Patches are alright as they are, but the unified diff seems incorrect.
+ if (vo_is_hidden_para in para.varoptions) and not
+ (vo_is_self in para.varoptions) then
+ continue;
should be included see "[PATCH 2/6] Added base for Reg/Off calculation
to paramgr"
I've also attached a simple test.
If you would rather have a unified diff, I can provide it.
mfg Steve
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20150413/db911f3f/attachment.html>
-------------- next part --------------
program TestInterfaceRTTI;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
classes, typinfo, variants;
type
TNumber = integer;
TNewNumber = type integer;
TIntegerArray = array of integer;
TNormalClass = class(TObject);
TSetOfByte = set of byte;
TEnum = (enOne, enTwo, enThree);
IMyNewMPInterface = interface['{AA503475-0187-4108-8E27-41475F4EF818}']
procedure TestRegister(A: integer; var B: string); register;
procedure TestStdCall(LongParaName: TObject; const B: string; var C: integer; out D: byte); stdcall;
procedure TestSafeCall(out R: integer); safecall;
function Number: TNumber; cdecl;
function NewNumber: TNewNumber; cdecl;
function AsString: string; pascal;
function AsString2: string; safecall;
procedure A2(const A: TIntegerArray);
procedure OkParam1(Value: TSetOfByte);
procedure OkParam2(Value: TEnum);
procedure OkParam3(Value: Variant);
procedure OkParam4(Value: TNormalClass);
function OkReturn1: shortstring;
function OkReturn2: TObject;
function OkReturn3: IInterface;
function OkReturn4: TSetOfByte;
function OkReturn5: TNormalClass;
function OkReturn6: TEnum;
function OkReturn7: TClass;
function OkReturn8: Pointer;
function OkReturn9: PChar;
function OkReturn10: TIntegerArray;
end;
function aligntoptr(p : pointer) : pointer;inline;
begin
{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
result:=align(p,sizeof(p));
{$else FPC_REQUIRES_PROPER_ALIGNMENT}
result:=p;
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
end;
function Skip(Value: PShortstring): pointer; overload;
begin
Result := Value;
Inc(PChar(Result), SizeOf(Value^[0]) + Length(Value^));
Result:=aligntoptr(result);
end;
function checkParam(
var p : Pointer;
const aName : ShortString;
aFlags : TParamFlags;
aType : PTypeInfo;
aReg : Byte;
aOff : LongInt) : Boolean;
var
localp:pointer;
begin
localp:=p;
with PVmtMethodParam(p)^ do
begin
if aFlags <> Flags then
exit(false);
inc(localp,SizeOf(TParamFlags));
localp:=aligntoptr(localp);
//if aType <> ParamType then
if aType <> PTypeInfo(ppointer(localp)^) then
exit(false);
inc(localp,SizeOf(PTypeInfo));
//if aReg <> ParReg then
if aReg <> PByte(localp)^ then
exit(false);
inc(localp,SizeOf(Byte));
//if aOff <> ParOff then
if aOff <> PLongInt(localp)^ then
exit(false);
inc(localp,SizeOf(LongInt));
//if aName <> Name then
if aName <> PShortString(localp)^ then
exit(false);
//p := Skip(@Name);
Inc(PChar(localp), SizeOf(PShortString(localp)^[0]) + Length(PShortString(localp)^));
p:=localp;
end;
result := true;
end;
function checkMethod(
var p : Pointer;
const aName : ShortString;
aMethodCC : TCallConv;
aResultType : PTypeInfo;
aStackSize : Word;
paramNames : array of ShortString;
paramFlags : array of TParamFlags;
paramTypes : array of PTypeInfo;
paramReg : array of Byte;
paramOff : array of LongInt) : Boolean;
var
I : SizeInt;
begin
if aName <> PIntfMethodEntry(p)^.Name then
exit(false);
//p := Skip(@PIntfMethodEntry(p)^.Name); // skip does not allign correct here !?
Inc(PChar(p), SizeOf(PShortString(p)^[0]) + Length(PShortString(p)^));
if 3 <> PByte(p)^ then
exit(false);
inc(p, sizeOf(Byte));
if aMethodCC <> PCallConv(p)^ then
exit(false);
inc(p, sizeOf(TCallConv));
if aResultType <> PPTypeInfo(p)^ then
exit(false);
inc(p, sizeOf(PTypeInfo));
if aStackSize <> PWord(p)^ then
exit(false);
inc(p, sizeOf(Word));
if length(paramNames) <> PByte(p)^ then
exit(false);
inc(p, sizeOf(Byte));
for I := 0 to high(paramNames) do
if not checkParam(p, paramNames[I], paramFlags[I], paramTypes[I], paramReg[I], paramOff[I]) then
exit(false);
result := true;
end;
function getMethodIntfTable(aTypeInfo : PTypeInfo) : PIntfMethodTable;
var
td : PTypeData;
p : Pointer;
propCount : SmallInt;
I : SizeInt;
begin
td := GetTypeData(aTypeInfo);
if aTypeInfo^.Kind = tkInterface then
p := skip(@td^.IntfUnit)
else
p := skip(@td^.IIDStr);
propCount := PSmallInt(p)^;
inc(p, sizeOf(SmallInt));
p:=aligntoptr(p);
for I := 0 to propCount - 1 do
begin
p := skip(@(PPropInfo(p)^.Name));
end;
result := p;
end;
var
count : SizeInt;
p : Pointer;
begin
p := getMethodIntfTable(TypeInfo(IMyNewMPInterface));
count := PIntfMethodTable(p)^.Count;
if count <> 22 then
halt(-1);
inc(p, SizeOf(TIntfMethodTable));
//procedure TestRegister(A: integer; var B: string); register;
if not checkMethod(p, 'TestRegister',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
nil,
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self','A','B'],
[[TParamFlag.pfAddress],[],[TParamFlag.pfVar]],
[TypeInfo(IMyNewMPInterface), TypeInfo(Integer), TypeInfo(String)],
{$IFDEF CPUi386}[0, 1, 2]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0, 1, 2]{$ENDIF CPUARM}
{$IFDEF win64}[0, 1, 2]{$ENDIF win64}
,
{$IFDEF CPUi386}[0, 0, 0]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0, 0, 0]{$ENDIF CPUARM}
{$IFDEF win64}[0, 0, 0]{$ENDIF win64}
) then
halt(-2);
//procedure TestStdCall(LongParaName: TObject; const B: string; var C: integer; out D: byte); stdcall;
if not checkMethod(p, 'TestStdCall', TCallConv.ccStdCall, nil,
{$IFDEF CPUi386}20{$ENDIF CPUi386}
{$IFDEF CPUARM}4{$ENDIF CPUARM}
{$IFDEF win64}40{$ENDIF win64},
['$self','LongParaName','B', 'C', 'D'],
[[TParamFlag.pfAddress],[TParamFlag.pfAddress],[TParamFlag.pfConst],[TParamFlag.pfVar],[TParamFlag.pfOut]],
[TypeInfo(IMyNewMPInterface), TypeInfo(TObject), TypeInfo(string), TypeInfo(integer), TypeInfo(byte)],
{$IFDEF CPUi386}[255, 255, 255, 255, 255]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0, 1, 2, 3, 255]{$ENDIF CPUARM}
{$IFDEF win64}[0, 1, 2, 3, 255]{$ENDIF win64}
,
{$IFDEF CPUi386}[0, 4, 8, 12, 16]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0, 0, 0, 0, 0]{$ENDIF CPUARM}
{$IFDEF win64}[0, 0, 0, 0, 32]{$ENDIF win64}
) then
halt(-2);
//procedure TestSafeCall(out R: integer); safecall;
if not checkMethod(p, 'TestSafeCall', TCallConv.ccSafeCall, nil,
{$IFDEF CPUi386}8{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self','R'],
[[TParamFlag.pfAddress],[TParamFlag.pfOut]],
[TypeInfo(IMyNewMPInterface), TypeInfo(integer)],
{$IFDEF CPUi386}[255, 255]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0, 1]{$ENDIF CPUARM}
{$IFDEF win64}[0, 1]{$ENDIF win64}
,
{$IFDEF CPUi386}[0, 4]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0, 0]{$ENDIF CPUARM}
{$IFDEF win64}[0, 0]{$ENDIF win64}
) then
halt(-3);
//function Number: TNumber; cdecl;
if not checkMethod(p, 'Number', TCallConv.ccCdecl, TypeInfo(TNumber),
{$IFDEF CPUi386}4{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
{$IFDEF CPUi386}[255]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0]{$ENDIF CPUARM}
{$IFDEF win64}[0]{$ENDIF win64}
,
{$IFDEF CPUi386}[0]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0]{$ENDIF CPUARM}
{$IFDEF win64}[0]{$ENDIF win64}
) then
halt(-4);
//function NewNumber: TNewNumber; cdecl;
if not checkMethod(p, 'NewNumber', TCallConv.ccCdecl, TypeInfo(TNewNumber),
{$IFDEF CPUi386}4{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
{$IFDEF CPUi386}[255]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0]{$ENDIF CPUARM}
{$IFDEF win64}[0]{$ENDIF win64}
,
{$IFDEF CPUi386}[0]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0]{$ENDIF CPUARM}
{$IFDEF win64}[0]{$ENDIF win64}
) then
halt(-5);
//function AsString: string; pascal;
if not checkMethod(p, 'AsString',
{$IFDEF CPUi386}TCallConv.ccPascal{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccStdCall{$ENDIF win64},
TypeInfo(String),
{$IFDEF CPUi386}8{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
{$IFDEF CPUi386}[255]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0]{$ENDIF CPUARM}
{$IFDEF win64}[0]{$ENDIF win64},
{$IFDEF CPUi386}[4]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0]{$ENDIF CPUARM}
{$IFDEF win64}[0]{$ENDIF win64}
) then
halt(-6);
//function AsString2: string; safecall;
if not checkMethod(p, 'AsString2', TCallConv.ccSafeCall, TypeInfo(String),
{$IFDEF CPUi386}8{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
{$IFDEF CPUi386}[255]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0]{$ENDIF CPUARM}
{$IFDEF win64}[0]{$ENDIF win64}
,
{$IFDEF CPUi386}[0]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0]{$ENDIF CPUARM}
{$IFDEF win64}[0]{$ENDIF win64}
) then
halt(-7);
//procedure A2(const A: TIntegerArray);
if not checkMethod(p, 'A2',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
nil,
{$IFDEF CPUi386}4{$ENDIF CPUi386}
{$IFDEF CPUARM}4{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self', 'A'],
[[TParamFlag.pfAddress], [TParamFlag.pfConst]],
[TypeInfo(IMyNewMPInterface), TypeInfo(TIntegerArray)],
{$IFDEF CPUi386}[0, 255]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0, 255]{$ENDIF CPUARM}
{$IFDEF win64}[0, 1]{$ENDIF win64}
,
{$IFDEF CPUi386}[0, 0]{$ENDIF CPUi386}
{$IFDEF CPUARM}[0, 0]{$ENDIF CPUARM}
{$IFDEF win64}[0, 0]{$ENDIF win64}
) then
halt(-8);
//procedure OkParam1(Value: TSetOfByte);
if not checkMethod(p, 'OkParam1',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
nil,
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self', 'Value'],
[[TParamFlag.pfAddress], []],
[TypeInfo(IMyNewMPInterface), TypeInfo(TSetOfByte)],
[0, 1],
[0, 0]
) then
halt(-9);
//procedure OkParam2(Value: TEnum);
if not checkMethod(p, 'OkParam2',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
nil,
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self', 'Value'],
[[TParamFlag.pfAddress], []],
[TypeInfo(IMyNewMPInterface), TypeInfo(TEnum)],
[0, 1],
[0, 0]
) then
halt(-10);
//procedure OkParam3(Value: Variant);
if not checkMethod(p, 'OkParam3',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
nil,
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self', 'Value'],
[[TParamFlag.pfAddress], []],
[TypeInfo(IMyNewMPInterface), TypeInfo(Variant)],
[0, 1],
[0, 0]
) then
halt(-11);
//procedure OkParam4(Value: TNormalClass);
if not checkMethod(p, 'OkParam4',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
nil,
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self', 'Value'],
[[TParamFlag.pfAddress], [TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface), TypeInfo(TNormalClass)],
[0, 1],
[0, 0]
) then
halt(-12);
//function OkReturn1: shortstring;
if not checkMethod(p, 'OkReturn1',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
TypeInfo(shortstring),
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
[0],
[0]
) then
halt(-13);
//function OkReturn2: TObject;
if not checkMethod(p, 'OkReturn2',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
TypeInfo(TObject),
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
[0],
[0]
) then
halt(-14);
//function OkReturn3: IInterface;
if not checkMethod(p, 'OkReturn3',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
TypeInfo(IInterface),
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
[0],
[0]
) then
halt(-15);
//function OkReturn4: TSetOfByte;
if not checkMethod(p, 'OkReturn4',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
TypeInfo(TSetOfByte),
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
[0],
[0]
) then
halt(-16);
//function OkReturn5: TNormalClass;
if not checkMethod(p, 'OkReturn5',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
TypeInfo(TNormalClass),
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
[0],
[0]
) then
halt(-17);
//function OkReturn6: TEnum;
if not checkMethod(p, 'OkReturn6',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
TypeInfo(TEnum),
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
[0],
[0]
) then
halt(-18);
//function OkReturn7: TClass;
if not checkMethod(p, 'OkReturn7',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
TypeInfo(TClass),
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
[0],
[0]
) then
halt(-19);
//function OkReturn8: Pointer;
if not checkMethod(p, 'OkReturn8',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
TypeInfo(Pointer),
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
[0],
[0]
) then
halt(-20);
//function OkReturn9: PChar;
if not checkMethod(p, 'OkReturn9',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
TypeInfo(PChar),
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
[0],
[0]
) then
halt(-21);
//function OkReturn10: TIntegerArray;
if not checkMethod(p, 'OkReturn10',
{$IFDEF CPUi386}TCallConv.ccReg{$ENDIF CPUi386}
{$IFDEF CPUARM}TCallConv.ccStdCall{$ENDIF CPUARM}
{$IFDEF win64}TCallConv.ccReg{$ENDIF win64},
TypeInfo(TIntegerArray),
{$IFDEF CPUi386}0{$ENDIF CPUi386}
{$IFDEF CPUARM}0{$ENDIF CPUARM}
{$IFDEF win64}32{$ENDIF win64},
['$self'],
[[TParamFlag.pfAddress]],
[TypeInfo(IMyNewMPInterface)],
[0],
[0]
) then
halt(-22);
writeln('Sucess!');
readln;
end.
More information about the fpc-devel
mailing list