[Previous] [Contents] [Next]

Chapter Fifteen

Standard Marshaling

In earlier chapters, we used the term standard marshaling to refer to marshaling code generated by the MIDL compiler since this generated code actually uses the standard marshaling technique. In this chapter, we'll discuss standard marshaling without the support of the MIDL compiler, and we'll introduce handler marshaling—a variation of marshaling that lies somewhere between standard marshaling and custom marshaling.

From the programmer's perspective, the main difference between standard marshaling and custom marshaling is that the standard marshaler provides built-in support for transmitting data between the proxy and the stub in all marshaling contexts. When you use custom marshaling, it is your responsibility to determine what form of communication is best for the job.

Standard marshaling is a specific implementation of the generic custom marshaling architecture, just as type library marshaling is a specific implementation of standard marshaling. Remember that both standard and custom marshaling are appropriate marshaling solutions for custom interfaces such as ISum. Most standard interfaces, such as IDispatch, already have marshaling code provided by Microsoft. You could replace this code with your own marshaling code, but this would be a fruitless effort.

Standard marshaling is the marshaling mechanism used by MIDL-generated proxy/stub code. However, you can write a proxy/stub DLL without using the MIDL compiler to generate the code. In many situations, handcrafted code is desirable. Recall the image-processing example from Chapter 14, in which clients sent bitmaps to an object for processing. These bitmaps might be very large and could bog down the network if the client and the object are run on different machines. To reduce the amount of network traffic when transferring large bitmaps, you can write proxy code that compresses the bitmap before sending it and stub code that decompresses the bitmap before forwarding it to the object. Granted, you can build such compression code directly into the client and the object, but doing so would place the burden of compression on the clients. Isolating the compression-related code in the proxy and the stub code insulates the client and the object from this bandwidth optimization.

When you use standard marshaling, you don't have to modify the client code or the object code. Instead, you build and register a single DLL containing both the proxy and stub code. Generally speaking, every custom interface needs a proxy/stub DLL for marshaling purposes. When an interface pointer is marshaled back to a client, the system automatically loads the proxy/stub DLL into the client's and the component's address spaces. The proxy object is instantiated in the client's address space; the stub object is instantiated in the component's address space.