Access violation after GetInterface/QueryInterface in Delphi
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 clas开发者_如何学JAVAs - 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?
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.
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!
I made a dll with COM from scratch and
- I use DllRegisterServer - it gave me a possibility to control server registration (over TComObjectFactory.RegisterClassObject in my first attempt)
- I remove QueryInterface from my TestComImpl
- Com4j supports only STA (Apartment) threading model (I assume RegisterClassObject uses MTA)
- So if class registered as Apartment (STA) or Both - com4j can create instances.
Thanks everyone for help!
精彩评论