0

I've come across some code that's throwing an exception (EIntfCasterror Cast not supported) when it passes nil to a constructor expecting a TComponent, like so:

obj := SomeClass.Create(nil);

The unit this is in does not contain a form and even TForm requires a TComponent be passed to it when you call its constructor. What should I pass in place of nil if anything exists or is there a way to get it to accept nil.

Thank you.

Also, I don't have the source code which calls the method this is in, or I would just have it pass the form it has access to.

EDIT: Fixed the code example.

EDIT2: Fixed the code example because I had a second brain fart when I first wrote it.

EDIT3: I don't have the code for the constructor either.

mnuzzo
  • 3,529
  • 4
  • 26
  • 29
  • 1
    That's not a constructor, that's a cast. Did you mean `SomeClass.Create(nil)`? – Blorgbeard Mar 24 '11 at 13:29
  • That's not even Delphi code. ;-) – Ondrej Kelle Mar 24 '11 at 13:42
  • You have not provided an accurate picture of your problem. That exception is not caused by the code you've posted. What line of code *inside* the constructor is executing when the exception is raised? What you've described does not happen in general, so the specific value of SomeClass is important. Please include it. – Rob Kennedy Mar 24 '11 at 13:59
  • I don't have that code either. – mnuzzo Mar 24 '11 at 14:04
  • @mnuzzo, try passing a Form or a DataModule as owner. Just put a button on a form and do `SomeClass.Create(Self)` from there, see if it works, and we'll take it from there. If you don't have the source for `SomeClass` and it doesn't accept either `TForm` or `TDataModule` as owner, you can't use it. ie: need to ask the developer what it wants as Owner. – Cosmin Prund Mar 24 '11 at 14:07
  • This might be an answer for you http://stackoverflow.com/questions/5420260/what-is-the-meaning-of-nil-owner-in-component-constructor. It's my cross reference :) The object you'll pass as the Owner will destroy your object. If you give there nil, you need to Free it by yourself. –  Mar 24 '11 at 14:10
  • @mnuzzo Do you have documentation about SomeClass, what's required to be passed as the parameter to the constructor will be stated there!! – jachguate Mar 24 '11 at 15:17
  • Nope. No documentation, no source code, first one to go where I'm going at this company. – mnuzzo Mar 24 '11 at 15:33
  • 1
    @Rob, upvote because it's an interesting puzzle: Why passing `nil` to a constructor causes a `EIntfCasterror` exception. Why the downvote? – Cosmin Prund Mar 24 '11 at 16:50

1 Answers1

2

EIntfCastError has nothing to do with the Owner passed in the constructor. It's because you try to cast an interface to another interface you think it supports when it doesn't in fact support it.

MyNewInterface := MyInterface as IADifferentInterface;

You're never ever required to pass in Owner, even when creating a TForm. The following code is perfectly legal:

var
  MyForm: TForm1;
begin
  MyForm := TForm1.Create(nil);
  try
    MyForm.ShowModal;
  finally
    MyForm.Free;
  end
end;

So is this (although it's pretty dumb - it illustrates the point, though):

implementation

var
  Button: TButton;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Button := TButton.Create(nil);
  Button.Parent := Form1;
  Button.Left := 10;
  Button.Top := 10;
  Button.Caption := 'Button';
  Button.Name := 'MyDumbButton';
  Button.OnClick := TheButtonClick;
end;

procedure TForm1.TheButtonClick(Sender: TObject);
begin
  ShowMessage(TButton(Sender).Name + ' clicked');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Button.Free;
end;
Ken White
  • 123,280
  • 14
  • 225
  • 444
  • 1
    nitpicking: I think EIntfCastError can also happen when casting an instance to an interface. – Ondrej Kelle Mar 24 '11 at 14:14
  • 3
    @TOndrej, technically, you're always casting an interface to an interface; When you call `TInterfacedObject as ISomething` you're actually invoking the `IUnknown.QueryInterface` method. – Cosmin Prund Mar 24 '11 at 14:16
  • @Cosmin, you beat me to it. :) – Ken White Mar 24 '11 at 14:22
  • Agreed but the cast to IInterface (or IUnknown) is not obvious, happening "behind the scenes" so I thought it's worth mentioning. – Ondrej Kelle Mar 24 '11 at 14:24
  • 1
    +1. A well behaved `TComponent` descendant should work fine with Owner=nil, but I don't think that's a requirement. For what it's worth, do we know for sure `SomeClass` is actually a `TComponent`? – Cosmin Prund Mar 24 '11 at 14:24