Struct FieldMarshalBuilder
pub struct FieldMarshalBuilder { /* private fields */ }Expand description
Builder for creating FieldMarshal metadata entries.
FieldMarshalBuilder provides a fluent API for creating FieldMarshal table entries
with validation and automatic blob management. Field marshaling defines the conversion
rules between managed and native types for fields and parameters during interop
scenarios including P/Invoke calls, COM interop, and platform invoke operations.
§Marshaling Model
.NET marshaling follows a structured pattern:
- Parent Entity: The field or parameter that requires marshaling
- Native Type: How the managed type appears in native code
- Conversion Rules: Automatic conversion behavior during calls
- Memory Management: Responsibility for allocation and cleanup
§Coded Index Types
Field marshaling uses the HasFieldMarshal coded index to specify targets:
- Field: Marshaling for struct fields and class fields
- Param: Marshaling for method parameters and return values
§Marshaling Scenarios and Types
Different native types serve various interop scenarios:
- Primitive Types: Direct mapping for integers, floats, and booleans
- String Types: Character encoding and memory management (ANSI, Unicode)
- Array Types: Element type specification and size management
- Pointer Types: Memory layout and dereferencing behavior
- Interface Types: COM interface marshaling and reference counting
- Custom Types: User-defined marshaling with custom marshalers
§Marshaling Descriptors
Marshaling information is stored as binary descriptors in the blob heap:
- Simple Types: Single byte indicating native type (e.g., NATIVE_TYPE_I4)
- Complex Types: Multi-byte descriptors with parameters (arrays, strings)
- Custom Marshalers: Full type name and initialization parameters
- Array Descriptors: Element type, dimensions, and size specifications
§Examples
let mut assembly = CilAssembly::new(view);
// Marshal a parameter as a null-terminated Unicode string
let param_ref = CodedIndex::new(TableId::Param, 1, CodedIndexType::HasFieldMarshal); // String parameter
let unicode_string_descriptor = vec![NATIVE_TYPE::LPWSTR]; // Simple descriptor
let string_marshal = FieldMarshalBuilder::new()
.parent(param_ref)
.native_type(&unicode_string_descriptor)
.build(&mut assembly)?;
// Marshal a field as a fixed-size ANSI character array
let field_ref = CodedIndex::new(TableId::Field, 1, CodedIndexType::HasFieldMarshal); // Character array field
let fixed_array_descriptor = vec![
NATIVE_TYPE::ARRAY,
0x04, // Array element type (I1 - signed byte)
0x20, 0x00, 0x00, 0x00, // Array size (32 elements, little-endian)
];
let array_marshal = FieldMarshalBuilder::new()
.parent(field_ref)
.native_type(&fixed_array_descriptor)
.build(&mut assembly)?;
// Marshal a parameter as a COM interface pointer
let interface_param = CodedIndex::new(TableId::Param, 2, CodedIndexType::HasFieldMarshal); // Interface parameter
let interface_descriptor = vec![NATIVE_TYPE::INTERFACE]; // COM interface
let interface_marshal = FieldMarshalBuilder::new()
.parent(interface_param)
.native_type(&interface_descriptor)
.build(&mut assembly)?;
// Marshal a return value as a platform-dependent integer
let return_param = CodedIndex::new(TableId::Param, 0, CodedIndexType::HasFieldMarshal); // Return value (sequence 0)
let platform_int_descriptor = vec![NATIVE_TYPE::INT]; // Platform IntPtr
let return_marshal = FieldMarshalBuilder::new()
.parent(return_param)
.native_type(&platform_int_descriptor)
.build(&mut assembly)?;Implementations§
§impl FieldMarshalBuilder
impl FieldMarshalBuilder
pub fn new() -> Self
pub fn new() -> Self
Creates a new FieldMarshalBuilder.
§Returns
A new crate::metadata::tables::fieldmarshal::FieldMarshalBuilder instance ready for configuration.
pub fn parent(self, parent: CodedIndex) -> Self
pub fn parent(self, parent: CodedIndex) -> Self
Sets the parent field or parameter that requires marshaling.
The parent must be a valid HasFieldMarshal coded index that references
either a field definition or parameter definition. This establishes which
entity will have marshaling behavior applied during interop operations.
Valid parent types include:
Field- Marshaling for struct fields in P/Invoke scenariosParam- Marshaling for method parameters and return values
Marshaling scope considerations:
- Field marshaling: Applied when the containing struct crosses managed/native boundary
- Parameter marshaling: Applied during each method call that crosses boundaries
- Return marshaling: Applied to return values from native methods
- Array marshaling: Applied to array elements and overall array structure
§Arguments
parent- AHasFieldMarshalcoded index pointing to the target field or parameter
§Returns
Self for method chaining.
pub fn native_type(self, native_type: &[u8]) -> Self
pub fn native_type(self, native_type: &[u8]) -> Self
Sets the native type marshaling descriptor.
The native type descriptor defines how the managed type should be represented and converted in native code. This binary descriptor is stored in the blob heap and follows .NET’s marshaling specification format.
Descriptor format varies by complexity:
- Simple types: Single byte (e.g.,
[NATIVE_TYPE::I4]for 32-bit integer) - String types: May include encoding and length parameters
- Array types: Include element type, dimensions, and size information
- Custom types: Include full type names and initialization parameters
Common descriptor patterns:
- Primitive:
[NATIVE_TYPE::I4]- 32-bit signed integer - Unicode String:
[NATIVE_TYPE_LPWSTR]- Null-terminated wide string - ANSI String:
[NATIVE_TYPE_LPSTR]- Null-terminated ANSI string - Fixed Array:
[NATIVE_TYPE_BYVALARRAY, element_type, size...]- In-place array - Interface:
[NATIVE_TYPE_INTERFACE]- COM interface pointer
§Arguments
native_type- The binary marshaling descriptor specifying conversion behavior
§Returns
Self for method chaining.
pub fn simple_native_type(self, type_id: u8) -> Self
pub fn simple_native_type(self, type_id: u8) -> Self
Sets a simple native type marshaling descriptor.
This is a convenience method for common marshaling scenarios that require only a single native type identifier without additional parameters.
§Arguments
type_id- The native type identifier from the NativeType constants
§Returns
Self for method chaining.
pub fn unicode_string(self) -> Self
pub fn unicode_string(self) -> Self
Sets Unicode string marshaling (LPWSTR).
This convenience method configures marshaling for Unicode string parameters and fields, using null-terminated wide character representation.
§Returns
Self for method chaining.
pub fn ansi_string(self) -> Self
pub fn ansi_string(self) -> Self
Sets ANSI string marshaling (LPSTR).
This convenience method configures marshaling for ANSI string parameters and fields, using null-terminated single-byte character representation.
§Returns
Self for method chaining.
pub fn fixed_array(self, element_type: u8, size: u32) -> Self
pub fn fixed_array(self, element_type: u8, size: u32) -> Self
Sets fixed-size array marshaling.
This convenience method configures marshaling for fixed-size arrays with specified element type and count. The array is marshaled in-place within the containing structure.
§Arguments
element_type- The native type of array elementssize- The number of elements in the array
§Returns
Self for method chaining.
pub fn com_interface(self) -> Self
pub fn com_interface(self) -> Self
Sets COM interface marshaling.
This convenience method configures marshaling for COM interface pointers, enabling proper reference counting and interface negotiation.
§Returns
Self for method chaining.
pub fn native_type_spec(self, native_type: NativeType) -> Self
pub fn native_type_spec(self, native_type: NativeType) -> Self
Sets marshaling using a high-level NativeType specification.
This method provides a type-safe way to configure marshaling using the
structured NativeType enum rather than raw binary descriptors. It automatically
encodes the native type specification to the correct binary format.
§Arguments
native_type- The native type specification to marshal to
§Returns
Self for method chaining.
§Note
If encoding fails, the error is stored and will be returned when build() is called.
§Examples
use dotscope::metadata::marshalling::NativeType;
use dotscope::metadata::tables::FieldMarshalBuilder;
// Unicode string with size parameter
let marshal = FieldMarshalBuilder::new()
.parent(param_ref)
.native_type_spec(NativeType::LPWStr { size_param_index: Some(2) })
.build(&mut assembly)?;
// Array of 32-bit integers
let array_marshal = FieldMarshalBuilder::new()
.parent(field_ref)
.native_type_spec(NativeType::Array {
element_type: Box::new(NativeType::I4),
num_param: Some(1),
num_element: Some(10),
})
.build(&mut assembly)?;pub fn marshalling_info(self, info: &MarshallingInfo) -> Self
pub fn marshalling_info(self, info: &MarshallingInfo) -> Self
Sets marshaling using a complete marshalling descriptor.
This method allows specifying complex marshalling scenarios with primary and additional types. This is useful for advanced marshalling cases that require multiple type specifications.
§Arguments
info- The complete marshalling descriptor with primary and additional types
§Returns
Self for method chaining.
§Note
If encoding fails, the error is stored and will be returned when build() is called.
§Examples
use dotscope::metadata::marshalling::{NativeType, MarshallingInfo};
use dotscope::metadata::tables::FieldMarshalBuilder;
let complex_info = MarshallingInfo {
primary_type: NativeType::CustomMarshaler {
guid: "12345678-1234-5678-9ABC-DEF012345678".to_string(),
native_type_name: "NativeArray".to_string(),
cookie: "size=dynamic".to_string(),
type_reference: "MyAssembly.ArrayMarshaler".to_string(),
},
additional_types: vec![NativeType::I4], // Element type hint
};
let marshal = FieldMarshalBuilder::new()
.parent(param_ref)
.marshalling_info(complex_info)
.build(&mut assembly)?;pub fn pointer(self, ref_type: Option<NativeType>) -> Self
pub fn pointer(self, ref_type: Option<NativeType>) -> Self
pub fn variable_array(
self,
element_type: NativeType,
size_param: Option<u32>,
element_count: Option<u32>,
) -> Self
pub fn variable_array( self, element_type: NativeType, size_param: Option<u32>, element_count: Option<u32>, ) -> Self
Sets marshaling for a variable-length array.
This convenience method configures marshaling for arrays with runtime size determination through parameter references.
§Arguments
element_type- The type of array elementssize_param- Optional parameter index for array sizeelement_count- Optional fixed element count
§Returns
Self for method chaining.
pub fn fixed_array_typed(
self,
element_type: Option<NativeType>,
size: u32,
) -> Self
pub fn fixed_array_typed( self, element_type: Option<NativeType>, size: u32, ) -> Self
pub fn native_struct(
self,
packing_size: Option<u8>,
class_size: Option<u32>,
) -> Self
pub fn native_struct( self, packing_size: Option<u8>, class_size: Option<u32>, ) -> Self
Sets marshaling for a native structure.
This convenience method configures marshaling for native structures with optional packing and size specifications.
§Arguments
packing_size- Optional structure packing alignment in bytesclass_size- Optional total structure size in bytes
§Returns
Self for method chaining.
pub fn safe_array(
self,
variant_type: u16,
user_defined_name: Option<String>,
) -> Self
pub fn safe_array( self, variant_type: u16, user_defined_name: Option<String>, ) -> Self
Sets marshaling for a COM safe array.
This convenience method configures marshaling for COM safe arrays with variant type specification for element types.
§Arguments
variant_type- VARIANT type constant for array elementsuser_defined_name- Optional user-defined type name
§Returns
Self for method chaining.
pub fn custom_marshaler(
self,
guid: &str,
native_type_name: &str,
cookie: &str,
type_reference: &str,
) -> Self
pub fn custom_marshaler( self, guid: &str, native_type_name: &str, cookie: &str, type_reference: &str, ) -> Self
Sets marshaling for a custom marshaler.
This convenience method configures marshaling using a user-defined custom marshaler with GUID identification and initialization parameters.
§Arguments
guid- GUID identifying the custom marshalernative_type_name- Native type name for the marshalercookie- Cookie string passed to the marshaler for initializationtype_reference- Full type name of the custom marshaler class
§Returns
Self for method chaining.
pub fn build(self, assembly: &mut CilAssembly) -> Result<ChangeRefRc>
pub fn build(self, assembly: &mut CilAssembly) -> Result<ChangeRefRc>
Builds the field marshal entry and adds it to the assembly.
This method validates all required fields are set, adds the marshaling descriptor to the blob heap, creates the raw field marshal structure, and adds it to the FieldMarshal table with proper token generation.
§Arguments
assembly- The assembly being modified
§Returns
A crate::metadata::token::Token representing the newly created field marshal entry, or an error if
validation fails or required fields are missing.
§Errors
- Returns error if encoding failed during
native_type_specormarshalling_info - Returns error if parent is not set
- Returns error if native_type is not set or empty
- Returns error if parent is not a valid HasFieldMarshal coded index
- Returns error if blob operations fail
- Returns error if table operations fail
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for FieldMarshalBuilder
impl !UnwindSafe for FieldMarshalBuilder
impl Freeze for FieldMarshalBuilder
impl Send for FieldMarshalBuilder
impl Sync for FieldMarshalBuilder
impl Unpin for FieldMarshalBuilder
impl UnsafeUnpin for FieldMarshalBuilder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for T
impl<T> Downcast for T
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian().Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.