If you do not need RTTI and were simply under the impression that this was the only way to call a protected method from anywhere other than within a sub-class, then there may another way to achieve what you want.
The protected visibility specifier in Delphi has a useful idiosyncracy: As well as limiting visibility to sub-classes, protected members are also visible to other classes declared in the same unit as those sub-classes. This enables a unit to gain access to the protected members of any arbitrary class by creating a sub-class and using that sub-class rather than the original. You can even use the sub-class to type-cast a reference to an instance that is a sub-class of the required base class incorporating the required protected methods, irrespective of the actual class of the object involved.
Strictly Speaking
This however does NOT apply if the methods are declared as strict protected. But as long as the methods are only protected, then you can use the technique.
By Way of Example
For example, The DestroyWindowHandle method of a VCL TWinControl is a protected method. But using this technique you can call this directly on any instance of a TWinControl, regardless of it's actual class. As a silly demonstration of this, consider a button that for some crazy reason wanted to directly destroy it's own underlying HWND when clicked, without destroying the button itself:
type
TWinControlEx = class(TWinControl);
procedure TMyForm.MyButtonClick(Sender: TObject);
begin
TWinControlEx(Sender).DestroyWindowHandle; // button window is destroyed but the button itself remains!
end;
This allows you access to protected methods on objects, but what about constructors, which are members of classes rather than objects ?
Well, the same principle applies. You can create a sub-class directly of the class you wish to instantiate and use that sub-class to instantiate an instance via the protected constructor as you normally would:
unit Unit2;
interface
type
TFoo = class
protected
constructor Create;
end;
implementation
constructor TFoo.Create;
begin
inherited Create;
// Foo specific, protected initialisation here....
end;
end.
And then in some other unit...
unit Unit1;
..
implementation
uses
Unit2;
type
TFooEx = class(TFoo);
procedure TMyForm.FormCreate(Sender: TObject);
var
foo: TFoo;
begin
foo := TFooEx.Create; // << the protected constructor!
end;
The caveat in this case however is that the foo instance is actually an instance of TFooEx and not TFoo. This may or may not be a problem in your case. A prime consideration is that any code that includes tests such as:
if foo is TFoo then
Will still work entirely as expected. However, more specific tests such as:
if foo.ClassType = TFoo then
Will not (since foo.ClassType = TFooEx, not TFoo).
Since the methods you are attempting to obtain access to are protected, your sub-class does not have to extend directly from the class that introduces the methods, but can extend any class that derives from that class. So, for example if the actual class you needed to instantiate is itself some sub-class of the (example) TFoo then you simply ensure that your class derives from that one, not the base:
// unit2
TFoo = class
protected
constructor Create; virtual;
end;
TBar = class(TFoo)
protected
constructor Create; override;
end;
And then in another unit...
TFooEx = class(TBar);
procedure ....;
var
foo: TFoo;
begin
foo := TFooEx.Create; // << creates a TBar using protected TBar constructor
end;
Advantages
One advantage of this over an RTTI based approach is that it avoids the need to have all that RTTI embedded in your application.
Another advantage is that if the signatures of the protected methods that you call in this way are changed then the code will simply not compile, rather than only failing at runtime. It also means you get assistance from code completion and insight when composing your constructor call, reducing the chance of making an error in the number or type of parameters.
TRttiType.GetMethods()
norTRttiType.GetDeclaredMethods()
will include protected methods/constructors. – Remy Lebeau