views:

319

answers:

3

Hi everyone!

First, I'm very new in Delphi and COM, but I should build COM application in Delphi. I read a lot of articles and notes on the internets, but COM and COM in Delphi are still not clear to me.

My sources - http://www.everfall.com/paste/id.php?wisdn8hyhzkt (about 80 lines).

I try to make a COM Interface and Impl class - it works if I call an interface method from Delphi (I create an impl object via TestClient.Create), but if I try to create an object from outer world (from Java, via com4j) my application crashed with following exception:

Project Kernel.exe raised exception class $C0000005 with 
message 'access violation at 0x00000002: read of address 0x00000002'.

If I set a breakpoint in QueryInterface - it breaks, but when I come out from function - all crashes.

What I'm doing wrong? What I still missing? What I can/should read about COM (in Delphi) to avoid dumb questions like this?

A: 

If the crash is happening after QueryInterface returns, what I would do is put a breakpoint in the Java app when it calls QueryInterface and see what it tries to do next. That'll give you an idea of where to look.

Your comment seems to bear this out. It's calling QueryInterface, getting back a result that says that this interface is good, and trying to use it for something that immediately breaks. But if you comment out the code that tells it the interface is good, it ends up not trying to use the interface, and nothing breaks.

If you're not familiar with Delphi, an access violation usually means a null pointer dereference. Here, it says that your instruction pointer is at memory location 0x000002. That probably means that you somehow tried to call a virtual method (or an interface method) on an object that hasn't been constructed yet.

Hope that helps!

Mason Wheeler
Thanks for reply, I will try to trace a 'java' side, but address 0x02 looks like GetInterface corrupts stack, but I think it's is imposible.
W55tKQbuRu28Q4xv
+2  A: 

There is no need to implement IUnkown.QueryInterface your self. Remove that method from TestComImpl and let TComObject handle it. Also be sure to give the ITestCom interface a GUID.

Lars Truijens
If I remove IUnknown.QueryInterface - com4j says that interface (ITestCom) not supported.
W55tKQbuRu28Q4xv
If that is the case, what does your object descend from?
Nick Hodges
Are you sure the interface has a IID(GUID) like this:ITestCom = interface(IUnknown)['{0D57624C-CDDE-458B-A36C-436AE465B477}'] procdure YourMethods;end;
Lars Truijens
Yes, I sure. Interface generated by midl and tlibimpl from .idl file. I will try to make dll with COM interfaces from scratch...
W55tKQbuRu28Q4xv
A: 

I made a dll with COM from scratch and

  1. I use DllRegisterServer - it gave me a possibility to control server registration (over TComObjectFactory.RegisterClassObject in my first attempt)
  2. I remove QueryInterface from my TestComImpl
  3. Com4j supports only STA (Apartment) threading model (I assume RegisterClassObject uses MTA)
  4. So if class registered as Apartment (STA) or Both - com4j can create instances.

Thanks everyone for help!

W55tKQbuRu28Q4xv