a missing functionality that could save me a lot of time today
a missing functionality that could save me a lot of time today
TypeOf(typed_variable) insteed of TypeOf(TVariableType)
the purpose is to use RTTI to load a complex API like this:
var
Sample: record
getText: function: PChar; stdcall;
setText: procedure(Value: PChar); stdcall;
end;
Sample.getText := GetProcAddress(dll, 'Sample_getText');
Sample.setText := GetProcAddress(dll, 'Sample_setText');
TypeOf(typed_variable) insteed of TypeOf(TVariableType)
the purpose is to use RTTI to load a complex API like this:
var
Sample: record
getText: function: PChar; stdcall;
setText: procedure(Value: PChar); stdcall;
end;
Sample.getText := GetProcAddress(dll, 'Sample_getText');
Sample.setText := GetProcAddress(dll, 'Sample_setText');
You might be able to use generics for that.
ReplyDeletefunction Foo(const param: T);
begin
if TypeOf(T) ... then
end;
Well, and then, how to use for the "Sample" record ?
ReplyDeleteNo I have to split the declaration
type
Sample = record
...
end;
var
SampleAPI: Sample;
LoadAPI(SampleAPI, TypeOf(Sample));
I now see what you mean. That's what you have BPL files for. Then te compiler takes care of everything.
ReplyDeleteIf Delphi had some decent type inference, Generics would do the trick. I still prefer the generics route as it is at least somewhat safer, as it'll complain if the type parameter and the variable type do not match.
ReplyDeletehttp://pastie.org/9664064
Nice code, it's almost what I've done, but as far as I know, the use of a generic duplicate the loader routine for each API...but it's exactly the same code ! (except line 41 on the call to TypeInfo)
ReplyDeleteI don't use Generic for that reason, I mean a TList could be nice to let the COMPILER check for correct type use, but a TList of TButton uses exactly the same code as a TList of TAnyThingElse, there's no reason to duplicate it.
Paul TOTH Well, yeah, personally I tend to accept the tradeoff in terms of increased productivity. But I agree it would be nice we had COMDAT folding in Delphi too.
ReplyDeletePaul TOTH And TList is *not* the same as TList, for an arbitrary TFoo. It may be the same, but it could also be different. If TFoo is a record type for example, the code will be different.
ReplyDeleteYes, that's what Constraints are for ;)
ReplyDeletePaul TOTH Right, but then we're back to the missing COMDAT folding. Which I agree is sorely missing.
ReplyDeleteI have a problem with Generic
ReplyDeletetype
TListAPI = record
function getItem: T; stdcall;
function nextItem: T;
end;
// specific THandle for 2 APIs
HItem1 = type THandle;
HItem2= type THandle;
var
API1: TListAPI;
API2: TListAPI;
function TListAPI.nextItem: T;
begin
result := getItem;
if Result = 0 then // <<-- do not compile :/
raise Exception.Create('item is null');
end;
AAAAHHHHAHAHAHAHAHA !!!!
ReplyDeleteprocedure TListAPI.Check(Value: T);
var
HValue: THandle absolute Value;
begin
if HValue = 0 then ...
end;
and then :
[dcc32 Erreur fatale] TestAPI.pas(3951): F2084 Erreur interne : AV06D82806-R00000000-0
THandle is not a valid constraint :(
ReplyDelete