Microsoft SDK for Java

Custom Marshaling Structures and Parameters

When specifying a structure or a parameter in a COM interface, it is sometimes necessary to indicate to the Microsoft VM exactly how the parameter or structure should be represented in native code. The @com.structmap directive is used to specify how fields in a Java structure are represented in native code. The @com.parameters directive is used to specify how parameters are represented in native code. These directives can indicate that the Java type should be marshaled by means of user-defined methods when creating the native code representation, and the Java representation from native code. To accomplish this task, the custom marshaler must implement two methods, toExternal and toJava. For example, the JCW representing the IPersistFile interface needs to specify the String parameter in the Load method as custom marshaled. The custom marshaler will be indicated in the parameter as a fully qualified Java class. This is shown in the following example:

@com.parameters([in, type=CUSTOM, 
customMarshal="com.ms.com.UniStringMarshaller"] pszFileName, 
[in, type=u4] dwMode)

The Microsoft VM uses com.ms.com.UniStringMarshaller to marshal the string that is passed as the pszFileName parameter. com.ms.com.UniStringMarshaller must implement the toExternal and toJava methods for performing the actual data marshaling. The Microsoft VM calls toExternal and passes the memory address that should be filled in with a native memory pointer to where the actual bytes representing the string are located. The Microsoft VM also calls toJava and passes the address in native memory where the bytes representing the string are located. The toJava method is called to construct the Java equivalent string from those bytes. The return value of toJava is assigned to the parameter that was specified to have the custom marshaler.

Some of the compiler directives have parameters that aid in custom marshaling. For instance, the @com.parameters and the @dll.structmap (and @com.structmap) directives have the CUSTOM, CUSTOMBYVAL, and CUSTOMBYREF parameters.

Use CUSTOM when one struct contains a pointer to another struct:

struct MyStruct {
int a;
struct PointerReferredStruct {
    float b;
} *c;
}

and when one of the parameters in a COM call is:

[in] struct* (HRESULT m([in]struct MyStruct *s);)

The parameter will be custom marshaled by the class specified by customMarshal in @com.parameters or @dll.structmap.

Use CUSTOMBYVAL when one struct is embedded inside another struct:

struct MyStruct {
int a;
struct EmbeddedStruct {
    float b;
} c;
}

and when a struct is passed by value in a COM call:

(HRESULT m([in]struct MyStruct s);)

The parameter will be custom marshaled as a by-value parameter. The custom marshaler class is specified by customMarshal in @com.parameters or @dll.structmap. The custom marshaler's copyToExternal method will be called to marshal the parameter to native code, and its copyToJava method will be called to marshal the value from native code to Java.

Use CUSTOMBYREF in COM calls where a struct is passed as:

[out] struct** (HRESULT m([out]struct MyStruct **s);).

The parameter will be custom marshaled as a by-reference value. The custom marshaler class is specified by customMarshal in @com.parameters or @dll.structmap. The custom marshaler's toExternal method will be called to marshal the parameter to native code, and its toJava method will be called to marshal the value from native code to Java.

© 1999 Microsoft Corporation. All rights reserved. Terms of use.