BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

QueryInterface reports E_NOINTERFACE with called from a serv

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OLE Automation
View previous topic :: View next topic  
Author Message
Ian Boyd
Guest





PostPosted: Thu Aug 17, 2006 7:27 am    Post subject: QueryInterface reports E_NOINTERFACE with called from a serv Reply with quote



i have a COM object written in Delphi, that we can instantiate fine from an
app:

procedure TForm1.Button1Click(Sender: TObject);
var
ClassID: TGUID;
o: IUnknown;
s: IExam;
const
IID_IExam: TGUID = '{7A794786-7C05-4EB4-A071-3D9B170B663A}';
CLSID_TestPaper: TGUID = '{4A75D28A-BCD3-46BF-BE91-361F2F207A10}';
begin
ClassID := CLSID_TestPaper;

o := CreateComObject(ClassID);

// s := o as IExam;
// if Failed(o.QueryInterface(IID_IExam, s) then
// if not Supports(o, IID_IExam, s) then

if Supports(o, IExam, s) then

ShowMessage('Smile')
else
ShowMessage('Sad');
end;

But if similar code is done from a service, then a call to Supports fails,
as does "as", and using QueryInterface directly returns 0x80004002
(E_NOINTERFACE)


i think the problem has to do with differing apartment models, and so COM is
trying to find some IMarshall interface, but it cannot. But before you think
about that, i'll confuse you with two other theories.


1. You just can't use Delphi COM dll's from a service. Maybe Delphi and it's
global variables (which make accessing visual controls from anything but the
main thread make impossible) make construcing COM objects from a service
impossible. There are global unit level routines, and singleton class
factories.

2. i create my objects during TService.OnStart event. i don't take advantage
of the OnExecute event and spawn worker threads. So, my service is single
threaded; and i STILL call CoInitialize/CoUninitialize during
OnStart/OnStop. So there's no problem there - but at least it can serve to
distract you from what the real problem probably is.



Now back to trying to figure it out. Overriding TComObject's
ObjQueryInterface method, i get to see all the interfaces being asked for by
COM when i try to load the object:

{00000000-0000-0000-C000-000000000046}: SUCCEEDED
{00000003-0000-0000-C000-000000000046}: FAILED
{0000001B-0000-0000-C000-000000000046}: FAILED
{00000000-0000-0000-C000-000000000046}: SUCCEEDED
{00000018-0000-0000-C000-000000000046}: FAILED
{00000019-0000-0000-C000-000000000046}: FAILED
{4C1E39E1-E3E3-4296-AA86-EC938D896E92}: FAILED
{7A794786-7C05-4EB4-A071-3D9B170B663A}: SUCCEEDED

Well that's quite a hodge-podge, but in the end it asks for my own IID, and
it returns.

So what's the rest?


IUnknown: SUCCEEDED
IMarshall: FAILED
"IdentityUnmarshal?": FAILED
IUnknown: SUCCEEDED
IStdMarshallInfo: FAILED
IExternalConnection: FAILED
???: FAILED
IExam: SUCCEEDED


So obviously COM is trying to do some cross apartment stuff. So my question
is, what do i have to do to my COM object so that it is compatible with the
apartment setup by a service?


My COM object is registered with Delphi as:

initialization
ComObjectFactory.Create(ComServer,
TTestPaper, CLSID_TestPaper, 'EyeExam', 'Dummy values changed for
the newgroup post',
ciMultiInstance,
tmApartment);

The last two are of course my concern. Also, my dll has no type library;
which has not been a problem when there was no marshalling. Does Delphi need
me to make a type library in order to automatically support marshalling? Can
Delphi EVER automtically support marshalling? Does TComObject ever get
marshalling ability? Should i be descending from some other type?


Or, more to the point, how can i get my DLL to be truly loaded into the
process space of the service application calling it? What specifically is
the cross-apartment issue?
Back to top
Dennis Passmore
Guest





PostPosted: Thu Aug 17, 2006 4:18 pm    Post subject: Re: QueryInterface reports E_NOINTERFACE with called from a Reply with quote



I have been using Delphi COM dlls in Delphi NT services for years. I have one Delphi NT Service
project that loads and uses a Delphi COM object that in itself loads and uses MsSql OLEDB as a COM
object and uses QueryInterface with no problems at all.


Dennis Passmore

"Think it might be a new experience and
if you can not Pull then at least Push
the job will get done"
Back to top
Ian Boyd
Guest





PostPosted: Thu Aug 17, 2006 5:54 pm    Post subject: Re: QueryInterface reports E_NOINTERFACE with called from a Reply with quote



Do your dll's have type libraries?


"Dennis Passmore" <dennisp (AT) nospam_dpassmore (DOT) com> wrote in message
news:g2k8e25hf4g8ab5atr2ujup1osqg06q14u (AT) 4ax (DOT) com...
Quote:
I have been using Delphi COM dlls in Delphi NT services for years. I have
one Delphi NT Service
project that loads and uses a Delphi COM object that in itself loads and
uses MsSql OLEDB as a COM
object and uses QueryInterface with no problems at all.


Dennis Passmore

"Think it might be a new experience and
if you can not Pull then at least Push
the job will get done"
Back to top
Dennis Passmore
Guest





PostPosted: Sat Aug 19, 2006 9:16 pm    Post subject: Re: QueryInterface reports E_NOINTERFACE with called from a Reply with quote

Quote:
Do your dll's have type libraries?

Sure they do but you have to use LoadRegTypeLib() to load the typelib into the NT service memory
space and then you can create the referenced forward interface functions you need access to.

Example:

type
TProgressFunc = class(TAutoIntfObject, IProgressfuncIntf)
private
fOwner: TObject;
protected
constructor Create;
procedure ProgressInfo(const Message: WideString); safecall;
end;

constructor TProgressFunc.Create;
var
ifTypeLib: ITypeLib;
begin
OleCheck(LoadRegTypeLib(LIBID_MyCalcs, 1, 0, 0, ifTypeLib));
inherited Create(ifTypeLib, IProgressfuncIntf);
end;

LIBID_MyCalcs is the GUID to the COM library declared in MyCalcs_TLB.pas and
IProgressfuncIntf is a Forward declaration defined in the same file.

Dennis Passmore

"Think it might be a new experience and
if you can not Pull then at least Push
the job will get done"
Back to top
Ian Boyd
Guest





PostPosted: Fri Aug 25, 2006 6:18 pm    Post subject: Re: QueryInterface reports E_NOINTERFACE with called from a Reply with quote

Quote:
Sure they do but you have to use LoadRegTypeLib() to load the typelib into
the NT service memory space and then you can create the referenced forward
interface functions you need access to.

Why?

What problem is this solving, how is it solving it, what am i doing to have
this problem, and why hasn't this problem happened before?

Windows already loads type libraries by itself. Why do it again?
Back to top
Dennis Passmore
Guest





PostPosted: Fri Aug 25, 2006 8:41 pm    Post subject: Re: QueryInterface reports E_NOINTERFACE with called from a Reply with quote

Quote:
Why?

What problem is this solving, how is it solving it, what am i doing to have
this problem, and why hasn't this problem happened before?


It is done so the calling application (a Nt Service in your case ) can create and use a interface
defined in a typelibrary without ever knowing how the interface is defined or implemented. Just
create a local case wrapper and call LoadRegTypeLib to load the typelib and create the interface
without ever knowing how it was implemented and built in the COM library.

I have a small example I can post if you need a sample.
Back to top
Ian Boyd
Guest





PostPosted: Fri Aug 25, 2006 10:24 pm    Post subject: Re: QueryInterface reports E_NOINTERFACE with called from a Reply with quote

Quote:
It is done so the calling application (a Nt Service in your case ) can
create and use a interface
defined in a typelibrary without ever knowing how the interface is defined
or implemented. Just
create a local case wrapper and call LoadRegTypeLib to load the typelib
and create the interface
without ever knowing how it was implemented and built in the COM library.

I have a small example I can post if you need a sample.

Yes please.


You can't just "create the interface", interfaces don't get created.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OLE Automation All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.