This sample is located in \Samples\Com\CustomMarshal\rect.
Note To use this sample, it is recommended that you have Microsoft® Visual C++® version 5.0 or higher installed.
Description
Using the Sample
Technologies Demonstrated
Other hook class examples have not provided methods for allocating or freeing memory for ETYPE itself. The examples relied entirely on the Microsoft virtual machine (Microsoft VM) to allocate the actual memory for ETYPE. As a result, the use of custom data types until now has been restricted to cases where ETYPE can be allocated on the stack and its lifetime is bounded by the lifetime of the call. While this is sufficient for some data types, there are cases where stack allocation is insufficient. The first case is when there is a need to marshal methods where an ETYPE is allocated by the callee but freed by the caller (or the other way around, as can happen with [in,out] parameters.) The second case is if the data type is variable-sized (such as a string), in which the Microsoft VM cannot do the stack-allocation because the size is unknown.
It is the responsibility of the hook class to specify which API is used to allocate and release the memory for ETYPE. The new hook methods required to support this are toExternal and releaseExternal.
Note This example could also have implemented copyToJava and toUninitJava here because Rect is mutable (like Point). However, for the sake of clarity, this was not done.
Important Even in the presence of these new marshaling methods, the Microsoft VM optimizes the output by allocating the data structure on the stack and thus overrides certain allocations. For example, for [in] ETYPE* calls, the COM method receives a pointer to a Microsoft VM-allocated ETYPE on the stack rather than one allocated by toExternal. If you want all ETYPEs allocated using toExternal, omit the cbByValSize field. This prevents the Microsoft VM from optimizing to stack allocations as it cannot predict how many bytes to allocate.
Use RectMarshaler as shown in the following table.
COM type | Marshaled to Java as |
HRESULT func([in] RECT) | func(Rect) |
HRESULT func([out,retval] RECT*) | Rect func() |
HRESULT func([in] RECT*) | func(Rect) |
HRESULT func([out] RECT*) | func(Rect[]) |
HRESULT func([in,out] RECT*) | func(Rect[]) |
HRESULT func([out,retval] RECT**) | Rect func() |
HRESULT func([in] RECT**) | func(Rect[]) |
HRESULT func([out] RECT**) | func(Rect[]) |
HRESULT func([in,out] RECT**) | func(Rect[]) |
To compile the sample
Use Nmake.exe to compile the makefile in the \Samples\Com\CustomMarshal\rect directory. Type the following command:
Nmake
To run the sample
Run Go.bat from the \Samples\Com\CustomMarshal\rundir directory.