Persistent DCOM Interface pointer in an ISAPI DLL made with Delphi 2006
22 Mrz 2007 22:44 In Category:Delphi
You have an
ISAPI DLL and like to perform outgoing COM/DCOM calls
? You either can setup the connection to the remote
Server in every call, which might not be the most
efficient way, or you can create the Interface
pointer once and use it in every call. In the
following I describe, how this
works.

Before you start coding in the DLL, there are a few steps you need to take care of. Because you use DCOM, you have to configure the Identity of the Website inside the IIS. You can do this by opening the Properties window of the virtual directory and change to the Tab sheet “Directory Security”. There you click in the group box “Authentication and access control” the Button Edit and enter select a User with sufficient rights on the Box, which runs the remote DCOM Server.
You also need to take care, that the User which runs the virtual directory and this means this User runs the ISPAI DLL, is allowed to “use” the DCOM Server on the remote machine. So open up DCOMCNFG on the remote machine and configure the Application there so that the entered User has Launch, Activation and Access Permissions for the DCOM Server Application.
After this security issues, you need to take care, that the COM Server is registered on the machine, which runs the IIS 6.0. Also take care, that the User which runs the ISAPI DLL has access file permissions to the folder, in which the .tlb/.exe files are you used to register the COM Server.
Now you can start using the DCOM Interface pointer in the Code of the ISAPI DLL. To have the pointer “global” you need to declare a pointer variable in the interface section of the implementation unit of the Webservice (MyWebserviceimpl.pas).
var
MyServerStream: Pointer;
implementation
This pointer is used to hold the Interface pointer and pass it between the threads in every call.
In the method, where you like to use the interface pointer you declare a variable of the real type
var
ILocalMyServer: IMyServer;
begin
Now you can create a connection to the remote Object, if not already done:
if MyServerStream = nil then
begin
// Create Stream if it is not there already
ILocalMyServer:=
(CreateRemoteComObject('SOME_COMPUTER’, CLASS_MyServer) as IMyServer);
//Pass the Interface pointer to the Stream
OleCheck(CoMarshalInterThreadInterfaceInStream(IID_IMyServer, ILocalMyServer,
IStream(MyServerStream)));
end;
And call a Interface method on the Remote Server:
//Get the Interface Pointer from the Stream
OleCheck(CoGetInterfaceAndReleaseStream(IStream(MyServerStream), IID_IMyServer, ILocalMyServer));
// Stream is invalid, make this clear
MyServerStream:= nil;
//Make the COM Call on the remote Server
ILocalMyServer.SomeFunction(SomeVar1, SomeVar2);
//Pass the Interface pointer to the Stream
OleCheck(CoMarshalInterThreadInterfaceInStream(IID_IMyServer, ILocalMyServer, IStream(MyServerStream)));
References:
- http://msdn2.microsoft.com/en-us/library/ms691421.aspx
- http://www.microsoft.com/germany/msdn/library/components/AchtLektionenZumThemaCOM.mspx?mfr=true
- http://groups.google.de/group/borland.public.delphi.oleautomation/browse_thread/thread/d698c5f4488d9411/ebbd31f28389dc6f?lnk=st&q=%22Interface+not+supported%22+ISAPI+Delphi&rnum=25&hl=de#ebbd31f28389dc6f
- http://groups.google.de/group/borland.public.delphi.internet/browse_thread/thread/3ef0aaae05a84af9/db2a9b25c0bfe63f?lnk=st&q=%22global+data%22+ISAPI+Delphi&rnum=3&hl=de#db2a9b25c0bfe63f

Before you start coding in the DLL, there are a few steps you need to take care of. Because you use DCOM, you have to configure the Identity of the Website inside the IIS. You can do this by opening the Properties window of the virtual directory and change to the Tab sheet “Directory Security”. There you click in the group box “Authentication and access control” the Button Edit and enter select a User with sufficient rights on the Box, which runs the remote DCOM Server.
You also need to take care, that the User which runs the virtual directory and this means this User runs the ISPAI DLL, is allowed to “use” the DCOM Server on the remote machine. So open up DCOMCNFG on the remote machine and configure the Application there so that the entered User has Launch, Activation and Access Permissions for the DCOM Server Application.
After this security issues, you need to take care, that the COM Server is registered on the machine, which runs the IIS 6.0. Also take care, that the User which runs the ISAPI DLL has access file permissions to the folder, in which the .tlb/.exe files are you used to register the COM Server.
Now you can start using the DCOM Interface pointer in the Code of the ISAPI DLL. To have the pointer “global” you need to declare a pointer variable in the interface section of the implementation unit of the Webservice (MyWebserviceimpl.pas).
var
MyServerStream: Pointer;
implementation
This pointer is used to hold the Interface pointer and pass it between the threads in every call.
In the method, where you like to use the interface pointer you declare a variable of the real type
var
ILocalMyServer: IMyServer;
begin
Now you can create a connection to the remote Object, if not already done:
if MyServerStream = nil then
begin
// Create Stream if it is not there already
ILocalMyServer:=
(CreateRemoteComObject('SOME_COMPUTER’, CLASS_MyServer) as IMyServer);
//Pass the Interface pointer to the Stream
OleCheck(CoMarshalInterThreadInterfaceInStream(IID_IMyServer, ILocalMyServer,
IStream(MyServerStream)));
end;
And call a Interface method on the Remote Server:
//Get the Interface Pointer from the Stream
OleCheck(CoGetInterfaceAndReleaseStream(IStream(MyServerStream), IID_IMyServer, ILocalMyServer));
// Stream is invalid, make this clear
MyServerStream:= nil;
//Make the COM Call on the remote Server
ILocalMyServer.SomeFunction(SomeVar1, SomeVar2);
//Pass the Interface pointer to the Stream
OleCheck(CoMarshalInterThreadInterfaceInStream(IID_IMyServer, ILocalMyServer, IStream(MyServerStream)));
References:
- http://msdn2.microsoft.com/en-us/library/ms691421.aspx
- http://www.microsoft.com/germany/msdn/library/components/AchtLektionenZumThemaCOM.mspx?mfr=true
- http://groups.google.de/group/borland.public.delphi.oleautomation/browse_thread/thread/d698c5f4488d9411/ebbd31f28389dc6f?lnk=st&q=%22Interface+not+supported%22+ISAPI+Delphi&rnum=25&hl=de#ebbd31f28389dc6f
- http://groups.google.de/group/borland.public.delphi.internet/browse_thread/thread/3ef0aaae05a84af9/db2a9b25c0bfe63f?lnk=st&q=%22global+data%22+ISAPI+Delphi&rnum=3&hl=de#db2a9b25c0bfe63f