Interfaced xls

Hi Adrian


I'm using an interfaced version of TXlsFile since my UDFs are in DLLs which cannot have explicit references to Flexcel units:

TInterfacedXls = class(TXlsFile, IInterface, IInterfacedXls)

In my udf Evaluate override I tried:

xls := arguments.Xls as IInterfacedXls;

However, this gives me an EFlexcelCoreException - 'There is no open file'.

Any idea what would cause this? If I comment-out the line the AV disappears and I use arguments.Xls successfully elsewhere in Evaluate so it looks like an invalid cast?

Thanks, Bob

Just a quick guess: Are you giving TInterfacedXls a GUID? 


Also does it work with an unsafe cast:
xls := IInterfacedXls(arguments.Xls);
?

Yes I've assigned a guid and the unsafe cast wouldn't compile - however, I've gone back to my test case and it now fails so it looks like I've screwed something up in the interfaced class. Will do more tests and get back to you.


Thanks, Bob

Hi Adrian,


Turns out my test case was fine, so I'm still struggling to get this working. It's definitely the cast that's causing the problem. I'll see if I can come up with a small test app and drop you an email.

Cheers, Bob 

Bob,


If you can send me something reproducible I'l be happy to take a look. I am leaving for 10 days tomorrow so support will be slower and focused only in emergencies, but I can look at it when I come back.
Bob,

I've been taking a look at the example you sent, and I think you are just having issues with reference counting. 

If you set a breakpoint in:

destructor TInterfacedXls.Destroy;
begin
  inherited;
end;


You'll see it is called when it shouldn't.



Also if you add the line:

 
xls := arguments.Xls as IInterfacedXls;  // -- This line causes an AV.
 xls._AddRef;


It will work fine. In a more conceptual view, you have a local interface variable in TGetValue.Evaluate:
  xls: IInterfacedXls;

which will be destroyed when it goes out of scope. But that variable isn't created by the method, it is casting a arguments.Xls variable which will be destroyed too, and it shouldn't.

All in all, the problem as always is that you need to be very careful when mixing objects and interfaces, and if possible avoid that. For this case, you could fix it by making TInterfacedXls a not refcounted object (you already override _AddRef and _Release in TInterfacedXls, but you kept the ref counting). Or if you want to keep it refcounted, then be very carefully and call _AddRef when needed.