3

With RttiContext.FindType('Classes.TStringList') I get RttiType of TStringList with no problem. But with RttiContext.FindType('MyUnit.TMyClass') I always get nil (of course MyUnit is in uses clause). Why, what is wrong?

Example:

unit MyUnit; 
interface 
uses 
  Classes; 
type 
  TMyClass = class(TStringList) 
  end; 
implementation 
end. 

Main unit: 
... 
uses 
  MyUnit,
... 
var 
  oCont: TRttiContext; 
  oType: TRttiType; 
begin 
  oCont := TRttiContext.Create; 
  try 
    oType := oCont.FindType('MyUnit.TMyClass'); <== oType = nil !! 
... 
Branko
  • 1,384
  • 1
  • 16
  • 35

2 Answers2

8

Probably the class has not included by the delphi linker in the final executable. A fast try can be the following:

  1. Declare a static method on your class. This method should be an empty method, a simple begin end.
  2. Call this static method in the initialization section of this unit.
  3. Ensure that the unit is referenced in your project somewhere.
  4. Now you should see the class with TRttiContext.FindType.
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Daniele Teti
  • 1,764
  • 14
  • 20
  • Thank you, you're right, class has not included in executable! After restart IDE I put reference to TMyClass im my code - GetType(TMyClass), so class was included in exe. That is reason why I get proper RttiType! – Branko Aug 12 '10 at 04:19
  • @Branko Glad to be useful. I've encountered this "issue" while develop a Delphi ORM with external config file. Every database adapter (or business logic class) have a reference only in the external file, so in the final executable there wasn't. So I've used the static-method trick. – Daniele Teti Aug 12 '10 at 10:58
  • This is a weak way to solve this problem. Because it compels you to modify the class. Better options can be found here: http://stackoverflow.com/a/10613212/576719 – David Heffernan Oct 03 '14 at 19:30
  • 2
    Even better IMHO is to call TMyClass.ClassName in the intialization section. Write a small comment to make clear why you are calling that property. – Daniele Teti Oct 03 '14 at 20:25
1

It could be a handful of things. Hard to say without seeing your code, but here are a few suggestions to look at. Is TMyClass a public type in the interface section? Is RTTI generation turned on for that unit? Is MyUnit in a package that hasn't been loaded yet?

Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
  • TMyClass is public type in the interface section, compiled without runtime packages. RTTI generation is not explicit turned on or off for MyUnit - how can I do this? – Branko Aug 11 '10 at 16:21
  • To simplify: unit MyUnit; interface uses Classes; type TMyClass = class(TStringList) end; implementation end. Code in main unit: ... uses MyUnit, ... var oCont: TRttiContext; oType: TRttiType; begin oCont := TRttiContext.Create; try oType := oCont.FindType('MyUnit.TMyClass'); <== oType = nil !! ... – Branko Aug 11 '10 at 16:37
  • @Branko: OK, try oCont.GetType(TMyClass) and see if that comes up with anything. That'll tell you whether RTTI exists for the class or not. If it exists, then FindType isn't finding it for some reason. – Mason Wheeler Aug 11 '10 at 16:45
  • @Mason - no problem, with GetType(TMyClass) I get proper RttiType, with oType.GetMethods / GetProperties I get all methods / properties for TStringList, TStrings, ... – Branko Aug 11 '10 at 16:53
  • @Branko: Then your issue is in FindType. First, double-check the obvious. Are you sure you aren't misspelling anything or putting in spaces or other characters that don't belong there? IF not, then you might need to trace into it, or have someone familiar with the RTTI system trace into it for you, to track down the problem. – Mason Wheeler Aug 11 '10 at 17:24
  • @Mason: Thank you for your efforts!! After close IDE and start Delphi again - no problems, everything works as it should be!? Now I know what needs to be done first if there is anything wrong. I already knew this but forgot :) – Branko Aug 11 '10 at 17:28
  • 1
    @Branko: you probably have seen an issue with Delphi that it thinks the sources are older than the compiled .dcu files. I have seen that before. Two solutions: restart Delphi, or delete the .dcu files and build your app. – Jeroen Wiert Pluimers Aug 11 '10 at 18:08
  • Please see my answer to Daniele Teti. – Branko Aug 12 '10 at 04:21