Any docs for creating DLLs or COM with D5?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Any docs for creating DLLs or COM with D5?

Costas
Is there any documentation or examples on how to create a simple COM
object exposing properties and methods?  Also how to create a DLL?

Regards,

Costas


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Bill Schwab-2
Costas,

> Is there any documentation or examples on how to create a simple COM
> object exposing properties and methods?

Look on the Wiki.


> Also how to create a DLL?

The package comment for the DLL deployment kit is terse but sufficient.  The
place to start is writing/compiling IDL to produce a type library (and maybe
a custom marshaling DLL), and then using the type library analyzer to create
wrapper classes, and then create the implementation.  Deployment as a DLL or
EXE is arguably an afterthought.

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Costas
Thanks Bill.

On Wed, 5 Jun 2002 21:06:11 -0400, "Bill Schwab"
<[hidden email]> wrote:

>Costas,
>
>> Is there any documentation or examples on how to create a simple COM
>> object exposing properties and methods?
>
>Look on the Wiki.
>
>
>> Also how to create a DLL?
>
>The package comment for the DLL deployment kit is terse but sufficient.  The
>place to start is writing/compiling IDL to produce a type library (and maybe
>a custom marshaling DLL), and then using the type library analyzer to create
>wrapper classes, and then create the implementation.  Deployment as a DLL or
>EXE is arguably an afterthought.
>
>Have a good one,
>
>Bill
>
>--
>Wilhelm K. Schwab, Ph.D.
>[hidden email]
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Jason Shannon
In reply to this post by Costas
On Thu, 06 Jun 2002 00:48:32 GMT, [hidden email] (Costas) wrote:

>Is there any documentation or examples on how to create a simple COM
>object exposing properties and methods?  Also how to create a DLL?

Hi,

There's a zip file at http://www.larch.demon.co.uk/dolphin/mathops.zip
that contains a package of COM components, an IDL file, and a C++ test
client. Between them, the components should show how to implement both
property getting and simple method calls. The package comment contains
various bits of information about building, deployment, testing, and
debugging that might be useful.

Cheers,
--
Jason Shannon http://www.araxis.com


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Keith Alcock-3
Jason,

It is very useful, but it appears to have been written for D4, at least
judging by the comments.  You write:

To debug a component, simply type 'COMObjectFactory register' (and the
same for each of the component class you're implementing) in a
Workspace.

There doesn't seem to be a COMObjectFactory class in my D5 image.  Also,
when you say to do the same for each component class, which classes are
those in your example?  Could you name them please?  Thank you.

Keith Alcock



Jason Shannon wrote:

>
> On Thu, 06 Jun 2002 00:48:32 GMT, [hidden email] (Costas) wrote:
>
> >Is there any documentation or examples on how to create a simple COM
> >object exposing properties and methods?  Also how to create a DLL?
>
> Hi,
>
> There's a zip file at http://www.larch.demon.co.uk/dolphin/mathops.zip
> that contains a package of COM components, an IDL file, and a C++ test
> client. Between them, the components should show how to implement both
> property getting and simple method calls. The package comment contains
> various bits of information about building, deployment, testing, and
> debugging that might be useful.
>
> Cheers,
> --
> Jason Shannon http://www.araxis.com


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Bill Schwab-2
Keith,

> It is very useful, but it appears to have been written for D4, at least
> judging by the comments.  You write:
>
> To debug a component, simply type 'COMObjectFactory register' (and the
> same for each of the component class you're implementing) in a
> Workspace.

I could be missing something, but one can generally send both #register and
#registerClassFactory to a COMInterfaceImp sub-class.  #register registers
the server so that COM can find it when it's not running, and
#registerClassFactory creates a class factory to make instances of the
component once the server is running.  Unless explicitly revoked, Dolphin
will re-register class factories each time the image loads.

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Jason Shannon
"Bill Schwab" <[hidden email]> wrote in message
news:ae2eud$3dfnr$[hidden email]...
> Keith,
>
> > It is very useful, but it appears to have been written for D4, at least
> > judging by the comments.  You write:
> >
> > To debug a component, simply type 'COMObjectFactory register' (and the
> > same for each of the component class you're implementing) in a
> > Workspace.

Uh, COMObjectFactory is a typo. It should be COMOperationFactory, which is
one of the classes in the package. :-)

The package is for D5. I haven't tried it on D4. To see the classes
(COMMathOperation COMAdditionOperation COMDivisionOperation
COMMultiplicationOperation COMOperationFactory MathOpsIOperation
MathOpsIOperationFactory) in the package, you could just use the D5 System
Browser on the $/jrs folder.

> I could be missing something, but one can generally send both #register
and
> #registerClassFactory to a COMInterfaceImp sub-class.  #register registers
> the server so that COM can find it when it's not running, and
> #registerClassFactory creates a class factory to make instances of the
> component once the server is running.  Unless explicitly revoked, Dolphin
> will re-register class factories each time the image loads.

Sounds right. I'll update the comments accordingly.

Cheers,
--
Jason Shannon http://www.araxis.com


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Keith Alcock-3
Jason,

Thank you very much for the example.  It is the first one that I've seen that
actually works and I hope that Costas has good luck with it.  I'm a little concerned
about it being quite a bit different than other examples, but it might be just
because yours has a dual interface and the others didn't.  It would be really nice if
the problem you mention could be tracked down:

<Jason>
The DLL will throw structured exceptions and cause access violations on shutdown
(when ::OleUninitialize) is called. There is probably some sort of
marshalling/reference counting bug in the DLL stub that's causing the DLL's
single-threaded apartment's proxies/stubs to try talking to dead interfaces during
apartment shutdown.
</Jason>

If it really is in the stub, then it would be a task for OA I presume.

On the other hand, I think that your example avoids the problem I am having because
the client uses CLSCTX_SERVER.  This seems to favor the inproc server even if Dolphin
is already running as an executable and has everything registered.  When the client
runs, a message about the image already being open appears.  This is probably because
the exe and the dll would both be trying to use the same image.  If I change the
client to use CLSCTX_LOCAL_SERVER, then various bad things happen like

Can't get create an instance of MathOps.OperationFactory: -2146959355

and a message from Dolphin

Fail to open image file 'C:\WINDOWS\Personal\Dolphin Smalltalk 5.0\Dolphin.img'.

Why it is looking for this image instead of Professional.img, I don't know yet, but
I'm about to track it down.  If I copy Professional.img to Dolphin.img, then the
client works.  Dolphin does, however, cause an error in USER.EXE and a nice dialog is
displayed for my customer to see.  Maybe that's a side-effect of the problem you
mention above.

Sometime soon I'll get to the bottom of this.  Thanks for helping.

Keith


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Keith Alcock-3
Please see related thread "Documentation on using Dolphin as COM server" for more information.


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Blair McGlashan
In reply to this post by Keith Alcock-3
"Keith Alcock" <[hidden email]> wrote in message
news:[hidden email]...
> Jason,
>
> Thank you very much for the example.  It is the first one that I've seen
that
> actually works and I hope that Costas has good luck with it.  I'm a little
concerned
> about it being quite a bit different than other examples, but it might be
just
> because yours has a dual interface and the others didn't.

Actually I think it is quite similar to the COM Random Stream sample
supplied with Dolphin XP, and that definitely works as intended (we have
tested it on fresh Dolphin installations on clean Windows 98, 2000 and XP
installations). The package is loaded in the image and you can find the
other required components in the following location:
    <my docs>\Dolphin Smalltalk 5.0\Object Arts\Samples\ActiveX\Random
A prebuilt type library and VB test client should be there. I will post some
detailed step-by-step instructions on how to deploy this sample as a DLL and
test it in a new thread (see "Instructions for testing the COM Random Stream
Sample").
>...It would be really nice if
> the problem you mention could be tracked down:
>
> <Jason>
> The DLL will throw structured exceptions and cause access violations on
shutdown
> (when ::OleUninitialize) is called. There is probably some sort of
> marshalling/reference counting bug in the DLL stub that's causing the
DLL's
> single-threaded apartment's proxies/stubs to try talking to dead
interfaces during
> apartment shutdown.
> </Jason>
>
> If it really is in the stub, then it would be a task for OA I presume.

When running under the C++ debugger it is quite normal for Dolphin to
generate certain structured exceptions that are handled, even "access
violations" (GP faults), since these are used by the memory manager to
detect when various memory areas need to be enlarged. Other "expected"
exception codes are 0x20000000 and 0x20000001, these being used to
exit/unwind callbacks in various circumstances.

I tested out Jason's sample running under the Visual C++ debugger with his
C++ client on Windows XP and I didn't see any unexpected/unhandled
structured exceptions. I haven't tried it on Windows 98 yet, but on that OS
the COM Random Stream sample runs and shuts down without issue.

>
> On the other hand, I think that your example avoids the problem I am
having because
> the client uses CLSCTX_SERVER.  This seems to favor the inproc server even
if Dolphin
> is already running as an executable and has everything registered.

If you want to test out running as a Local Server then you must either make
sure that the class creation context excludes CLSCTX_INPROC_SERVER (as I see
you have done), or you must remove the InProcServer32 key created by
COMInterfaceImp class>>register. On the whole I would recommend removing the
key since with many clients it is not possible to specify the class creation
context flags, and Dolphin itself cannot be used as a test client where the
implementation is an in-proc development image.

You can the InProcServer32 registration like this:

    key := (RegKey classesRoot at: 'CLSID') at: COMRandomStream clsid
asString.
    key removeKey: 'InProcServer32'.

>...  When the client
> runs, a message about the image already being open appears.  This is
probably because
> the exe and the dll would both be trying to use the same image.

Some background. When you are running an image that has registered a class
factory (COMInterfaceImp class>>registerClassFactory) then if you attempt to
create instances of that from within that image, those requests will be
serviced by that image. We describe this as "in-image" mode, which is very
useful for testing as everything is running in-process within the same
apartment so no marshalling code is needed. For example:

    COMRandomStream registerClassFactory.
    r := IRandomStream new.

When a class factory is registered in a certain way it takes priority over
all registry entries - see the MSDN documentation for
CoRegisterClassObject() and the REGCLS enumeration. Note in particular: "If
both the REGCLS_MULTIPLEUSE and CLSCTX_LOCAL_SERVER are set in a call to
CoRegisterClassObject, the class object is also automatically registered as
an in-process server, whether or not CLSCTX_INPROC_SERVER is explicitly set.
" This will be the case for class factories registered by Dolphin.

Should you not have a class factory registered by a running server, then the
in-proc server registration will take precedence if CLSCTX_SERVER is
specified. Note that you cannot debug Dolphin servers in-process with the
Dolphin development environment as the test client. This would require
loading two images into the same VM, which is not supported. You can run a
deployed Dolphin DLL with the Dolphin IDE as the client, but to debug
in-process you must use some other client.

You can debug with Dolphin as both client and server if the Dolphin server
runs out of process. To achieve this you need to revoke any class factory
registration in the client, and delete the InProcServer32 key. But...

>...If I change the
> client to use CLSCTX_LOCAL_SERVER, then various bad things happen like
>
> Can't get create an instance of MathOps.OperationFactory: -2146959355
>
> and a message from Dolphin
>
> Fail to open image file 'C:\WINDOWS\Personal\Dolphin Smalltalk
5.0\Dolphin.img'.
>

> Why it is looking for this image instead of Professional.img, I don't know
yet, but
> I'm about to track it down.  If I copy Professional.img to Dolphin.img,
then the
> client works.

As I alluded in a previous posting, the COMInterfaceImp class>>register
method does not create the correct LocalServer32 registry entry for
debugging (it is OK for the self-registration of a deployed server). The
command line needs to specify the image to load. I have appended below a
patched version of the method (and another useful patch) which fixes this.
Without this patch Dolphin.exe just attempts to load "Dolphin.img" from the
working directory. The "Image" key cannot be used by a local server on
startup, since it doesn't know in advance what CLSIDs it will be expected to
service, therefore the image to run must be included on the command line.


> ...Dolphin does, however, cause an error in USER.EXE and a nice dialog is
> displayed for my customer to see.  Maybe that's a side-effect of the
problem you
> mention above.

I see no such issue with the COM Random Stream sample running on Windows 98,
either using the deployed DLL, or debugging out of process. As I say I found
no problem with Jason's server either when running on XP, but I've yet to
try it on 9x.

Regards

Blair

--------------------------------

"DVE - #963"!

!COMInterfaceImp class methodsFor!

register
 "Make the necessary registry entries to expose the receiver as a COM object
which can be used by
 other applications. This (along with #unregister) provides the necessary
mechanism for self-registration."

 "Gather all information up front to try and avoid creating a partial entry"

 | key desc clsid pid vipid imageFileName |
 clsid := self clsid asString.
 pid := self progID.
 desc := self progDescription.
 vipid := self versionIndependentProgID.
 imageFileName := SessionManager current imageFileName.

 "First the ProgID and version independent Prog ID mapping to the CLSID."
 key := RegKey classesRoot.
 key at: pid put: desc.
 (key at: pid) at: 'CLSID' put: clsid.
 key at: vipid put: desc.
 (key at: vipid)
  at: 'CLSID' put: clsid;
  at: 'CurVer' put: pid.

 "Now the CLSID to server .EXE mapping."
 key := RegKey classesRoot at: 'CLSID'.
 key at: clsid put: desc.
 key := key at: clsid.
 key at: 'ProgID' put: pid.
 SessionManager current isDLL
  ifTrue:
   ["Register the image DLL as the in-proc component"

   key at: 'InProcServer32' put: imageFileName]
  ifFalse:
   ["Register the .EXE as a local server for this component"

   | inProcStub commandLine |
   commandLine := String writeStream.
   commandLine
    nextPut: $";
    nextPutAll: (ExternalLibrary moduleFileName: nil);
    nextPut: $".
   SessionManager current isRuntime
    ifFalse:
     [commandLine
      space;
      nextPut: $";
      nextPutAll: imageFileName;
      nextPut: $"].
   key at: 'LocalServer32' put: commandLine contents.

   "For an executable image we can register the standard in-proc stub for
   CLSCTX_INPROC_SERVER activation, but only if it is available"
   inProcStub := FileLocator installRelative localFileSpecFor: (self
inprocSurrogate: false).
   (File exists: inProcStub)
    ifTrue:
     ["Register the standard in-proc stub as supporting this component when
loaded in-proc, in which
     case we must also add an additional key so that the stub can find the
image."

     key
      at: 'InProcServer32' put: inProcStub;
      at: 'Image' put: imageFileName]]! !
!COMInterfaceImp class categoriesFor: #register!operations!public! !

"DVE - #972"!

!DevelopmentSessionManager methodsFor!

traceStream
 ^(self isHeadless not and: [Transcript notNil]) ifTrue: [Transcript]
ifFalse: [Trace]! !
!DevelopmentSessionManager categoriesFor: #traceStream!accessing!private! !

!DevelopmentSessionManager methodsFor!

trace: aString
 "Append aString to the trace stream."

 (self traceStream)
  nextPutAll: aString;
  flush! !
!DevelopmentSessionManager categoriesFor: #trace:!operations-logging!public!
!


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Blair McGlashan
"Blair McGlashan" <[hidden email]> wrote in message
news:ae7bs3$4igpa$[hidden email]...
> ...
> As I alluded in a previous posting, the COMInterfaceImp class>>register
> method does not create the correct LocalServer32 registry entry for
> debugging (it is OK for the self-registration of a deployed server). The
> command line needs to specify the image to load. I have appended below a
> patched version of the method (and another useful patch) which fixes this.
>...

Sorry, I attached the wrong version of the patch. The correct one is below:

Regards

Blair

--------------------------

"DVE - #963"!

!COMInterfaceImp class methodsFor!

register
 "Make the necessary registry entries to expose the receiver as a COM object
which can be used by
 other applications. This (along with #unregister) provides the necessary
mechanism for self-registration."

 | key desc clsid pid vipid imageFileName |


 "Gather all information up front to try and avoid creating a partial entry"
 clsid := self clsid asString.
 pid := self progID.
 desc := self progDescription.
 vipid := self versionIndependentProgID.
 imageFileName := SessionManager current imageFileName.

 "First the ProgID and version independent Prog ID mapping to the CLSID."
 key := RegKey classesRoot.
 key at: pid put: desc.
 (key at: pid) at: 'CLSID' put: clsid.
 key at: vipid put: desc.
 (key at: vipid)
  at: 'CLSID' put: clsid;
  at: 'CurVer' put: pid.

 "Now the CLSID to server .EXE mapping."
 key := RegKey classesRoot at: 'CLSID'.
 key at: clsid put: desc.
 key := key at: clsid.
 key at: 'ProgID' put: pid.
 SessionManager current isDLL
  ifTrue:
   ["Register the image DLL as the in-proc component"

   key at: 'InProcServer32' put: imageFileName]
  ifFalse:
   ["Register the .EXE as a local server for this component"

   | inProcStub commandLine |
   commandLine := String writeStream.
   commandLine nextPutAll: (ExternalLibrary moduleFileName: nil).
   SessionManager current isRuntime
    ifFalse:
     [commandLine
      space;
      nextPut: $";
      nextPutAll: imageFileName;
      nextPut: $"].
   key at: 'LocalServer32' put: commandLine contents.

   "For an executable image we can register the standard in-proc stub for
   CLSCTX_INPROC_SERVER activation, but only if it is available"
   inProcStub := FileLocator installRelative localFileSpecFor: (self
inprocSurrogate: false).
   (File exists: inProcStub)
    ifTrue:
     ["Register the standard in-proc stub as supporting this component when
loaded in-proc, in which
     case we must also add an additional key so that the stub can find the
image."

     key
      at: 'InProcServer32' put: inProcStub;
      at: 'Image' put: imageFileName]]! !
!COMInterfaceImp class categoriesFor: #register!operations!public! !

"DVE - #972"!

!DevelopmentSessionManager methodsFor!

traceStream
 ^(self isHeadless not and: [Transcript notNil]) ifTrue: [Transcript]
ifFalse: [Trace]! !
!DevelopmentSessionManager categoriesFor: #traceStream!accessing!private! !

!DevelopmentSessionManager methodsFor!

trace: aString
 "Append aString to the trace stream."

 (self traceStream)
  nextPutAll: aString;
  flush! !
!DevelopmentSessionManager categoriesFor: #trace:!operations-logging!public!
!


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Jason Shannon
In reply to this post by Blair McGlashan
"Blair McGlashan" <[hidden email]> wrote in message
news:ae7bs3$4igpa$[hidden email]...

> When running under the C++ debugger it is quite normal for Dolphin to
> generate certain structured exceptions that are handled, even "access
> violations" (GP faults), since these are used by the memory manager to
> detect when various memory areas need to be enlarged. Other "expected"
> exception codes are 0x20000000 and 0x20000001, these being used to
> exit/unwind callbacks in various circumstances.
>
> I tested out Jason's sample running under the Visual C++ debugger with his
> C++ client on Windows XP and I didn't see any unexpected/unhandled
> structured exceptions. I haven't tried it on Windows 98 yet, but on that
OS
> the COM Random Stream sample runs and shuts down without issue.

I've included the debugger output that shows the problems. I'm using WinXP
Pro with VS.NET to get this.

'cppclient.exe': Loaded 'C:\Documents and Settings\jrs\My Documents\Dolphin
Smalltalk 5.0\jrs\COM\MathOps\cppclient.exe', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\ole32.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\user32.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\msvcp70d.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\msvcr70d.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\imm32.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\lpk.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\usp10.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\uxtheme.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\pgphk.dll', No symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\msctf.dll', No symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\SynTPFcs.dll', No symbols
loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\version.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\clbcatq.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\oleaut32.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\comres.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\temp\mathops.dll', No symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\winmm.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\msvcp60.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\shlwapi.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\comctl32.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\serwvdrv.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\umdmxfrm.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\msi.dll', Symbols loaded.
'cppclient.exe': Loaded 'C:\WINDOWS\system32\sxs.dll', Symbols loaded.
Server shutdown request
First-chance exception at 0x77e6d756 (kernel32.dll) in cppclient.exe:
0x80010108: The object invoked has disconnected from its clients.
First-chance exception at 0x77e6d756 (kernel32.dll) in cppclient.exe:
0xA0000204: 0xa0000204.
First-chance exception at 0x77e6d756 (kernel32.dll) in cppclient.exe:
0x80010108: The object invoked has disconnected from its clients.
First-chance exception at 0x77e6d756 (kernel32.dll) in cppclient.exe:
0x800401FD: Object is not connected to server.
The thread '__endthreadex' (0xd8) has exited with code 0 (0x0).
First-chance exception at 0x771ccbd1 (ole32.dll) in cppclient.exe:
0xC0000005: Access violation reading location 0x001524a8.
'cppclient.exe': Unloaded 'C:\temp\mathops.dll'
'cppclient.exe': Unloaded 'C:\WINDOWS\system32\comctl32.dll'
'cppclient.exe': Unloaded 'C:\WINDOWS\system32\shlwapi.dll'
'cppclient.exe': Unloaded 'C:\WINDOWS\system32\msvcp60.dll'
The thread 'Win32 Thread' (0x220) has exited with code 0 (0x0).
The thread 'main' (0x230) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0xebc) has exited with code 0 (0x0).
The program '[3980] cppclient.exe: Native' has exited with code 0 (0x0).

I should note that it doesn't happen *all* the time, and sometimes the
exceptions are slightly different. It happens most often when stepping
slowly through the cppclient.exe in the debugger. If the problems occur,
then they always occur when stepping over the ::OleUninitialize() at the
end.

The call stack at the time of an "The object invoked has disconnected from
its clients" is:

  kernel32.dll!_RaiseException@16()  + 0x50
  rpcrt4.dll!_RpcpRaiseException@4()  + 0x1c
  rpcrt4.dll!_NdrProxySendReceive@8()  + 0x1f85
  rpcrt4.dll!_NdrClientCall2()  + 0x96a
  rpcrt4.dll!_ObjectStublessClient@8()  + 0x5b
  rpcrt4.dll!_ObjectStubless@0()  + 0xf
  ole32.dll!RemoteReleaseRifRefHelper()  + 0x3d
  ole32.dll!RemoteReleaseRifRef()  + 0x60
  ole32.dll!CStdMarshal::DisconnectCliIPIDs()  + 0x1f5
  ole32.dll!CStdMarshal::Disconnect()  + 0x91b
  ole32.dll!DisconnectSwitch()  + 0x12
  ole32.dll!CStdMarshal::DisconnectAndRelease()  + 0x2c
  ole32.dll!COIDTable::ThreadCleanup()  + 0xe645
  ole32.dll!FinishShutdown()  + 0x3f
  ole32.dll!ApartmentUninitialize()  + 0x4b
  ole32.dll!wCoUninitialize()  + 0x32
  ole32.dll!_CoUninitialize@0()  + 0x5dee
  ole32.dll!_OleUninitialize@0()  + 0x2e
> cppclient.exe!main(int argc=0x00000001, char * * argv=0x008430d0)  Line 69
C++
  cppclient.exe!mainCRTStartup()  Line 400 + 0x11 C
  kernel32.dll!_BaseProcessStart@4()  + 0x23

The call stack at the time of an "Object is not connected to server" is:

> kernel32.dll!_RaiseException@16()  + 0x50
  rpcrt4.dll!_RpcpRaiseException@4()  + 0x1c
  rpcrt4.dll!_NdrProxySendReceive@8()  + 0x1f85
  rpcrt4.dll!_NdrClientCall2()  + 0x96a
  rpcrt4.dll!_ObjectStublessClient@8()  + 0x5b
  rpcrt4.dll!_ObjectStubless@0()  + 0xf
  ole32.dll!RemoteReleaseRifRefHelper()  + 0x3d
  ole32.dll!RemoteReleaseRifRef()  + 0x60
  ole32.dll!CStdMarshal::DisconnectCliIPIDs()  + 0x1f5
  ole32.dll!CStdMarshal::Disconnect()  + 0x91b
  ole32.dll!CStdIdentity::~CStdIdentity()  + 0x6e
  ole32.dll!CStdIdentity::`vector deleting destructor'()  + 0x8
  ole32.dll!CStdIdentity::CInternalUnk::Release()  + 0x3339
  rpcrt4.dll!_IUnknown_Release_Proxy@4()  + 0xd
  mathops.dll!00e9d981()
  mathops.dll!00e9d85b()
  mathops.dll!00e893e7()
  mathops.dll!00eabe17()
  mathops.dll!00ea5100()
  mathops.dll!00e930e4()
  kernel32.dll!_BaseThreadStart@8()  + 0x37

I have another application (MFC) that uses an in-process Dolphin COM
component. Doing a LoadLibrary on the DLL and calling DllRegisterServer
always causes:

First-chance exception at 0x77e6d756 (kernel32.dll) in Merge.exe:
0xA0000204: 0xa0000204.

The call stack is:

> kernel32.dll!_RaiseException@16()  + 0x50
  mergeutil.dll!01f1cf3b()
  mergeutil.dll!01f1cfff()
  mergeutil.dll!01ef93e7()
  mergeutil.dll!01f1be17()
  mergeutil.dll!01f15100()
  mergeutil.dll!01f030e4()
  kernel32.dll!_BaseThreadStart@8()  + 0x37

I often get the problems noted above for cppclient during application
shutdown too - again when ::OleUninitialize is called.

I'd be happy to try out a version of the Dolphin COM stub that has debug
information (for the call stack at least) if that would help narrow the
problem down.

Best regards,
--
Jason Shannon http://www.araxis.com


Reply | Threaded
Open this post in threaded view
|

Re: Any docs for creating DLLs or COM with D5?

Blair McGlashan
"Jason Shannon" <[hidden email]> wrote in message
news:3d074266$0$233$[hidden email]...
> ....
> I've included the debugger output that shows the problems. I'm using WinXP
> Pro with VS.NET to get this.
>
> 'cppclient.exe': Loaded 'C:\Documents and Settings\jrs\My
Documents\Dolphin

> Smalltalk 5.0\jrs\COM\MathOps\cppclient.exe', Symbols loaded.
>... Server shutdown request
> First-chance exception at 0x77e6d756 (kernel32.dll) in cppclient.exe:
> 0x80010108: The object invoked has disconnected from its clients.
> First-chance exception at 0x77e6d756 (kernel32.dll) in cppclient.exe:
> 0xA0000204: 0xa0000204.
> First-chance exception at 0x77e6d756 (kernel32.dll) in cppclient.exe:
> 0x80010108: The object invoked has disconnected from its clients.
> First-chance exception at 0x77e6d756 (kernel32.dll) in cppclient.exe:
> 0x800401FD: Object is not connected to server.
> The thread '__endthreadex' (0xd8) has exited with code 0 (0x0).
> First-chance exception at 0x771ccbd1 (ole32.dll) in cppclient.exe:
> 0xC0000005: Access violation reading location 0x001524a8.
>...
> I should note that it doesn't happen *all* the time, and sometimes the
> exceptions are slightly different. It happens most often when stepping
> slowly through the cppclient.exe in the debugger. If the problems occur,
> then they always occur when stepping over the ::OleUninitialize() at the
> end.
>
>....
> I have another application (MFC) that uses an in-process Dolphin COM
> component. Doing a LoadLibrary on the DLL and calling DllRegisterServer
> always causes:
>
> First-chance exception at 0x77e6d756 (kernel32.dll) in Merge.exe:
> 0xA0000204: 0xa0000204.
>...
> I often get the problems noted above for cppclient during application
> shutdown too - again when ::OleUninitialize is called.
>
> I'd be happy to try out a version of the Dolphin COM stub that has debug
> information (for the call stack at least) if that would help narrow the
> problem down.

Thanks. I would "expect" the 0xA0000204, because of the way that Dolphin
communicates between image and the stub using COM interfaces - on shutdown
the image disconnects from the stub during a COM method call in from the
stub. It is possible that this could be avoided, but it should be safe. The
access violations, however, should not be occurring. I will raise a defect
report and get it looked into.

Regards

Blair