Skip to main content

Module marshalling

Module marshalling 

Expand description

Implementation of the type marshalling for native code invokations Type marshalling for native code invocations and COM interop in .NET assemblies.

This module provides constants, types, and logic for parsing and representing native type marshalling as defined in ECMA-335 II.23.2.9 and extended by CoreCLR. It supports marshalling for P/Invoke, COM interop, and other native interop scenarios.

§Marshalling Overview

.NET marshalling converts managed types to/from native types for interoperability:

  • P/Invoke: Platform Invoke for calling unmanaged functions in DLLs
  • COM Interop: Communication with Component Object Model interfaces
  • Windows Runtime: Integration with WinRT APIs and types
  • Custom Marshalling: User-defined type conversion logic

§Supported Native Types

The implementation supports all native types from ECMA-335 and CoreCLR:

  • Primitive Types: Integers, floats, booleans, characters
  • String Types: ANSI, Unicode, UTF-8 strings with various encodings
  • Array Types: Fixed arrays, variable arrays, safe arrays
  • Pointer Types: Raw pointers with optional type information
  • Interface Types: COM interfaces (IUnknown, IDispatch, IInspectable)
  • Structured Types: Native structs with packing and size information
  • Custom Types: User-defined marshalling with custom marshalers

§Marshalling Descriptors

Marshalling information is encoded as binary descriptors containing:

  1. Primary Type: The main native type to marshal to/from
  2. Parameters: Size information, parameter indices, and type details
  3. Additional Types: Secondary types for complex marshalling scenarios
  4. End Marker: Termination indicator for descriptor boundaries

§Thread Safety

All types in this module are thread-safe:

  • Constants: Immutable static values
  • Enums/Structs: No internal mutability
  • Parsers: Stateless after construction

§Key Components

§Examples

§Parsing Simple Types

use dotscope::metadata::marshalling::{parse_marshalling_descriptor, NativeType, NATIVE_TYPE};

// Parse a simple LPSTR marshalling descriptor
let descriptor_bytes = &[NATIVE_TYPE::LPSTR, 0x05]; // LPSTR with size param 5
let info = parse_marshalling_descriptor(descriptor_bytes)?;

match info.primary_type {
    NativeType::LPStr { size_param_index: Some(5) } => {
        println!("LPSTR with size parameter index 5");
    }
    _ => unreachable!(),
}

§Parsing Complex Arrays

use dotscope::metadata::marshalling::{MarshallingParser, NativeType, NATIVE_TYPE};

// Parse an array descriptor: Array<I4>[param=3, size=10]
let descriptor_bytes = &[
    NATIVE_TYPE::ARRAY,
    NATIVE_TYPE::I4,
    0x03,  // Parameter index 3
    0x0A   // Array size 10
];

let mut parser = MarshallingParser::new(descriptor_bytes);
let native_type = parser.parse_native_type()?;

match native_type {
    NativeType::Array { element_type, num_param, num_element } => {
        println!("Array of {:?}, param: {:?}, size: {:?}",
                 element_type, num_param, num_element);
    }
    _ => unreachable!(),
}

§Working with Custom Marshalers

use dotscope::metadata::marshalling::NativeType;

match native_type {
    NativeType::CustomMarshaler { guid, native_type_name, cookie, type_reference } => {
        println!("Custom marshaler: GUID={}, Type={}, Cookie={}, Ref={}",
                 guid, native_type_name, cookie, type_reference);
    }
    _ => { /* Handle other types */ }
}

§Encoding Marshalling Descriptors

use dotscope::metadata::marshalling::{encode_marshalling_descriptor, NativeType, MarshallingInfo};

// Create a marshalling descriptor
let info = MarshallingInfo {
    primary_type: NativeType::LPStr { size_param_index: Some(5) },
    additional_types: vec![],
};

// Encode to binary format
let bytes = encode_marshalling_descriptor(&info)?;
// Result: [NATIVE_TYPE::LPSTR, 0x05]

Modules§

NATIVE_TYPE
Native type constants as defined in ECMA-335 II.23.2.9 and CoreCLR extensions.
VARIANT_TYPE
COM VARIANT type constants for safe array marshalling.

Structs§

MarshallingEncoder
Encoder for marshaling descriptors.
MarshallingInfo
Represents a complete marshaling descriptor.
MarshallingParser
Parser for marshaling descriptors.

Enums§

NativeType
Represents a native type for marshalling between managed and unmanaged code.

Constants§

MAX_RECURSION_DEPTH
Maximum recursion depth for parsing marshaling descriptors.

Functions§

encode_marshalling_descriptor
Encodes a marshaling descriptor to bytes.
parse_marshalling_descriptor
Parses a marshaling descriptor from bytes.