Jump to content
dormky

How do I get a Pointer to a generic type ?

Recommended Posts

I'm trying to use TRttiField.SetValue with a generic type.

 

TTestClass = class(TObject)
  testValue: Integer;
end;

function testProc<T>() : TArray<T>;
  //
  // Code to get the relevant field...
  //
  field.SetValue(Result[i], TValue.From<Integer>(47)); // Fails : E2010 Incompatible types: 'Pointer' and 'T'
end;

If I try to make a PByte(Result) myself, this also fails with an incompatible typecast.

All a want is the address of my field so I can write a value there.

 

Thanks !

 

Edit : Okay, found an horrendous solution :

procedure makeCopy(var dest; value: Variant; field: TRttiField);
begin
  field.SetValue(Pointer(dest), TValue.FromVariant(value));
end;

This works for my simple field, probably won't for more complex stuff. You end up with an additional function call for every SetValue just to get around the compiler, but alas...

Edited by dormky

Share this post


Link to post
4 hours ago, dormky said:

I'm trying to use TRttiField.SetValue with a generic type.

 


TTestClass = class(TObject)
  testValue: Integer;
end;

function testProc<T>() : TArray<T>;
  //
  // Code to get the relevant field...
  //
  field.SetValue(Result[i], TValue.From<Integer>(47)); // Fails : E2010 Incompatible types: 'Pointer' and 'T'
end;

 

The code shown is too incomplete to make sense, but in general a generic class is just a blueprint, it has no actual class representation and thus no RTTI in itself. You have to work with a specific derived type to get RTTI. That unfortunately makes it hard to impossible to do some things in the generic class itself.

Share this post


Link to post
1 hour ago, PeterBelow said:

The code shown is too incomplete to make sense, but in general a generic class is just a blueprint, it has no actual class representation and thus no RTTI in itself. You have to work with a specific derived type to get RTTI. That unfortunately makes it hard to impossible to do some things in the generic class itself.

That's totally correct, but the fact that I can't grab a Pointer directly but there's a simple workaround shows that this is a (probably willful) limitation of the compiler.

Share this post


Link to post

Please make a complete compilable executable example. The listed code does not illustrate proper generic references.

 

It is not clear what you are trying to achieve, it being manipulating an input value or an internal value, nor what value you are trying to modify.

If you are using pointer references to modify values, your code isn´t really generic anymore.

 

  • Like 1

Share this post


Link to post

The 1st parameter of TRttiField.SetValue() expects a pointer to an object instance that the field belongs to, not a pointer to the field itself.  Your function's Result is an array of T, is T an object type?  If so, then you should constrain T with the 'class' constraint so that the compiler knows T is a class type, and thus Result is an array of object pointers.

 

Can you provide a more complete example of what exactly you are trying to accomplish? Where are you getting the TRttiField from to begin with?

Edited by Remy Lebeau
  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×