remotemono
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
remotemono::RMonoVariant Class Reference

#include <RMonoVariant_Def.h>

Collaboration diagram for remotemono::RMonoVariant:
Collaboration graph
[legend]

Classes

class  MonoObjectPtrWrapper
 
struct  RawPtr
 

Public Types

enum  Type { TypeInvalid = 0, TypeValue = 1, TypeMonoObjectPtr = 2, TypeRawPtr = 3 }
 
enum  Direction { DirectionDefault = 0 << 3, DirectionIn = 1 << 3, DirectionOut = 2 << 3, DirectionInOut = 3 << 3 }
 
typedef RMonoVariant Self
 

Public Member Functions

 RMonoVariant ()
 
 RMonoVariant (const Self &other)
 
template<typename T , typename Enable = std::enable_if_t<!std::is_base_of_v<MonoObjectPtrWrapper, T>>>
 RMonoVariant (T val)
 
template<typename T >
 RMonoVariant (T *val)
 
 RMonoVariant (void *data, size_t size, bool copy=false)
 
 RMonoVariant (const RMonoObjectPtr &v, bool autoUnbox=true)
 
 RMonoVariant (RMonoObjectPtr &&v, bool autoUnbox=true)
 
 RMonoVariant (RMonoObjectPtr *v, bool autoUnbox=true)
 
 RMonoVariant (const MonoObjectPtrWrapper &v, bool autoUnbox=true)
 
 RMonoVariant (std::nullptr_t)
 
 RMonoVariant (rmono_voidp v, RawPtr)
 
 RMonoVariant (rmono_voidp *v, RawPtr)
 
Selfoperator= (const Self &other)
 
Self forDirection (Direction dir) const
 
Self in () const
 
Self out () const
 
Self inout () const
 
bool isValid () const
 
Type getType () const
 
Direction getDirection () const
 
void setDirection (Direction dir)
 
void setAutoUnboxEnabled (bool autoUnbox)
 
bool isAutoUnboxEnabled () const
 
bool isNullPointer () const
 
size_t getValueSize () const
 
void * getValueData ()
 
const void * getValueData () const
 
template<typename T >
getValue () const
 
RMonoObjectPtr getMonoObjectPtr () const
 
rmono_voidp getRawPtr () const
 
template<typename ABI >
size_t getRemoteMemorySize (ABI &abi, size_t &alignment) const
 
template<typename ABI >
void copyForRemoteMemory (ABI &abi, void *buf) const
 
template<typename ABI >
void updateFromRemoteMemory (ABI &abi, RMonoAPIBase &mono, void *buf)
 

Static Public Member Functions

static constexpr size_t getMaxRequiredAlignment ()
 

Static Public Attributes

static const struct remotemono::RMonoVariant::RawPtr rawPtr = {}
 

Detailed Description

A special class that can encapsulate any instance of a Mono/.NET reference or value type. This means it can hold any of the following:

This type is mostly used in certain places where the raw Mono API has a void* parameter or return value referring to a managed value, e.g. the value in mono_field_set_value() or mono_object_unbox(). It is also used in functions like mono_runtime_invoke() for the method parameters (as an element of a RMonoVariantArray).

We use object of this class instead of simple void* values for multiple reasons:

  1. It contains info about what kind of type is stored in it (value type, reference type or raw pointer). This is useful e.g. for reference types (i.e. MonoObject*): Here we keep rmono_gchandles instead of the raw pointers to be on the safe side of the Mono GC. Because we don't want to pin the GC handles, we must actually pass the GC handle itself to the remote process and convert back to the raw pointer just-in-time. To do this, RemoteMono's generated wrapper functions need to know if the value it receives is such a GC handle or not.
  2. For value types, it stores them together with info about their size. We need that when copying the values to and from remote memory.
  3. It contains additional metadata necessary for calling certain Mono API functions. E.g. for mono_runtime_invoke(), we need to know if each parameter is an input, output, or both. That's because mono_runtime_invoke() needs parameters (specifically reference types) to be passed differently depending on this directionality. This class can provide this information (see forDirection()).

This documentation may reference C# types, but it is not actually specific to C# remotes.

Member Enumeration Documentation

◆ Direction

Direction of the value contained in the variant.

This is only useful when calling Mono API functions whose parameters are not always of a fixed directionality. One such example is mono_runtime_invoke(), where the directionality of each parameter depends on how the method was defined (e.g. in C# whether the out or ref modifiers were used for a parameter). In this case, you must specify the direction if it differs from the default (see the parameter tags in the function definition in RMonoAPIBackend).

For example: For mono_runtime_invoke(), you must pass out-params (C# out) and inout-params (C# ref) using DirectionOut and DirectionInOut, respectively. Not doing so (even if you don't care about the result of an out-param) will lead to crashes.

See also
forDirection()
in()
out()
inout()
Enumerator
DirectionDefault 

Direction not specified.

This is the default for all variants and means that the variant uses the direction that is the default for whatever Mono API function it's used in.

DirectionIn 

Input direction (local value is passed to remote Mono API function, but is not read back).

DirectionOut 

Output direction (undefined value is passed to remote Mono API function, but the new value after the call is read back).

DirectionInOut 

Both directions.

◆ Type

Enumerator
TypeValue 

A value type instance that is kept in local memory, and always copied over on-demand when a Mono API function is invoked. Used for both built-in value types (e.g. C# int, byte, float) and custom value types (e.g. C# structs).

TypeMonoObjectPtr 

An instance of a reference type, i.e. the GC handle of a MonoObject*.

TypeRawPtr 

A raw pointer in remote memory. Gets passed directly to any Mono API functions.

Constructor & Destructor Documentation

◆ RMonoVariant() [1/11]

remotemono::RMonoVariant::RMonoVariant ( )
inline

Creates an invalid variant, passed as a NULL pointer to Mono API functions.

◆ RMonoVariant() [2/11]

remotemono::RMonoVariant::RMonoVariant ( const Self other)
inline

Copy constructor.

◆ RMonoVariant() [3/11]

template<typename T , typename Enable = std::enable_if_t<!std::is_base_of_v<MonoObjectPtrWrapper, T>>>
remotemono::RMonoVariant::RMonoVariant ( val)
inline

Creates an object of a value type.

This is equivalent to calling RMonoVariant(&val, sizeof(T), true), i.e. it copies the data.

Parameters
valThe value.
See also
RMonoVariant(void*, size_t, bool)

◆ RMonoVariant() [4/11]

template<typename T >
remotemono::RMonoVariant::RMonoVariant ( T *  val)
inline

Creates an object of a value type in user-provided memory.

This is equivalent to calling RMonoVariant(val, sizeof(T), false), i.e. it does not copy the data, but stores the pointer directly.

Parameters
valPointer to the value.
See also
RMonoVariant(void*, size_t, bool)

◆ RMonoVariant() [5/11]

remotemono::RMonoVariant::RMonoVariant ( void *  data,
size_t  size,
bool  copy = false 
)
inline

Creates an object of a value type from a buffer.

Can be used for two purposes:

  1. For C# built-in value types (e.g. int, float, byte), in which case you can just pass a pointer to a variable of the corresponding C++ type (e.g. int32_t, float, uint8_t).
  2. For any custom value types, in which case you can pass a pointer to the equivalent C++ struct (be aware of alignment and other details), or to a raw buffer that you received from another Mono API call.

The data can either be copied into the variant object itself, or the object can simply store a pointer to the user-supplied memory. In the latter case, the user has to ensure that the data remains valid for as long as the RMonoVariant object is used. Storing a direct pointer can be useful for getting output values into user-supplied variables without unnecessary copying.

If the variant is used for an output-only value, you can also pass a pointer to uninitialized memory, as long as the memory is large enough to hold the expected value type.

Parameters
dataPointer to the value type object's data. May be NULL, in which case a raw NULL pointer will be passed to the Mono API.
sizeSize of the value type object's data in bytes.
copytrue if the object should make a copy of the data, false if it should store the pointer directly.

◆ RMonoVariant() [6/11]

remotemono::RMonoVariant::RMonoVariant ( const RMonoObjectPtr v,
bool  autoUnbox = true 
)
inline

Creates a variant containing an RMonoObjectPtr, i.e. an object of a class derived from System.Object.

This version will copy the RMonoObjectPtr.

Parameters
vThe object pointer.
autoUnboxWhether to enable auto-unboxing of boxed value types. See #FlagDisableAutoUnbox.

◆ RMonoVariant() [7/11]

remotemono::RMonoVariant::RMonoVariant ( RMonoObjectPtr &&  v,
bool  autoUnbox = true 
)
inline

Creates a variant containing an RMonoObjectPtr, i.e. an object of a class derived from System.Object.

This version will copy the RMonoObjectPtr.

Parameters
vThe object pointer.
autoUnboxWhether to enable auto-unboxing of boxed value types. See #FlagDisableAutoUnbox.

◆ RMonoVariant() [8/11]

remotemono::RMonoVariant::RMonoVariant ( RMonoObjectPtr v,
bool  autoUnbox = true 
)
inline

Creates a variant containing an RMonoObjectPtr, i.e. an object of a class derived from System.Object.

This version will not copy the RMonoObjectPtr, but keep store the pointer directly. The user has to ensure that the memory remains valid for as long as the RMonoVariant object is used.

Parameters
vPointer to the object pointer.
autoUnboxWhether to enable auto-unboxing of boxed value types. See #FlagDisableAutoUnbox.

◆ RMonoVariant() [9/11]

remotemono::RMonoVariant::RMonoVariant ( std::nullptr_t  )
inline

Creates a null value.

This will just pass a raw NULL pointer to the Mono API functions.

◆ RMonoVariant() [10/11]

remotemono::RMonoVariant::RMonoVariant ( rmono_voidp  v,
RawPtr   
)
inlineexplicit

Creates a variant that represents a raw pointer in remote memory. The pointer is passed directly to any Mono API functions. The caller must ensure that it is valid in the context of the remote process.

Use RMonoVariant::rawPtr for the second parameter. It is just a constructor overload disambiguation tag.

Parameters
vThe raw pointer in remote memory.

◆ RMonoVariant() [11/11]

remotemono::RMonoVariant::RMonoVariant ( rmono_voidp *  v,
RawPtr   
)
inlineexplicit

Creates a variant that represents a raw pointer in remote memory. The pointer is passed directly to any Mono API functions. The caller must ensure that it is valid in the context of the remote process.

This version of the constructor takes a pointer to the raw remote pointer, and can be used to receive raw pointers returned from a Mono API function.

Use RMonoVariant::rawPtr for the second parameter. It is just a constructor overload disambiguation tag.

Parameters
vPointer to the raw pointer in remote memory.

Member Function Documentation

◆ copyForRemoteMemory()

template<typename ABI >
void remotemono::RMonoVariant::copyForRemoteMemory ( ABI &  abi,
void *  buf 
) const

Copy this variant's value to a buffer that can then be transferred to remote memory. The buffer must have at least getRemoteMemorySize(abi) bytes of free memory.

Parameters
abiThe ABI to use for converting the value.
bufThe buffer to copy the value into.

◆ forDirection()

Self remotemono::RMonoVariant::forDirection ( Direction  dir) const
inline

Return an alias of this object that has the given explicit directionality.

See also
Direction
in()
out()
inout()

◆ getMaxRequiredAlignment()

static constexpr size_t remotemono::RMonoVariant::getMaxRequiredAlignment ( )
inlinestaticconstexpr

Return the maximum alignment that any value could possibly require in remote memory.

◆ getMonoObjectPtr()

RMonoObjectPtr remotemono::RMonoVariant::getMonoObjectPtr ( ) const
inline

Return the underlying RMonoObjectPtr.

You may only call this if the variant is of type TypeMonoObjectPtr.

◆ getRawPtr()

rmono_voidp remotemono::RMonoVariant::getRawPtr ( ) const
inline

Return the underlying raw remote pointer.

You may only call this if the variant is of type TypeRawPtr.

◆ getRemoteMemorySize()

template<typename ABI >
size_t remotemono::RMonoVariant::getRemoteMemorySize ( ABI &  abi,
size_t &  alignment 
) const

Get the number of bytes required to hold this variant's value in the remote process.

Parameters
abiThe ABI to use for determining the size.
alignmentThe minimum alignment for the value.
Returns
The value size in bytes.

◆ getType()

Type remotemono::RMonoVariant::getType ( ) const
inline

Return this variant's type.

◆ getValue()

template<typename T >
T remotemono::RMonoVariant::getValue ( ) const
inline

Get a copy of the stored value type data (reinterpret-casted to T).

This may only be called if the variant is of type TypeValue.

◆ getValueData() [1/2]

void* remotemono::RMonoVariant::getValueData ( )
inline

Get a pointer to the stored value type data.

This may only be called if the variant is of type TypeValue.

◆ getValueData() [2/2]

const void* remotemono::RMonoVariant::getValueData ( ) const
inline

Get a pointer to the stored value type data.

This may only be called if the variant is of type TypeValue.

◆ getValueSize()

size_t remotemono::RMonoVariant::getValueSize ( ) const
inline

Get the size of the stored value type, in bytes.

This may only be called if the variant is of type TypeValue.

◆ in()

Self remotemono::RMonoVariant::in ( ) const
inline

Return a DirectionIn alias of this object.

◆ inout()

Self remotemono::RMonoVariant::inout ( ) const
inline

Return a DirectionInOut alias of this object.

◆ isAutoUnboxEnabled()

bool remotemono::RMonoVariant::isAutoUnboxEnabled ( ) const
inline

Determines whether automatic unboxing of boxed value type objects is enabled.

◆ isNullPointer()

bool remotemono::RMonoVariant::isNullPointer ( ) const
inline

Determine if this variant is a null pointer. Note that this can only be true for output value type variants, or for input custom value type variants. A variant of type TypeMonoObjectPtr that is null will return false.

See also
isNullValue()

◆ isValid()

bool remotemono::RMonoVariant::isValid ( ) const
inline

Determine if this is a valid variant. Note that things like null pointers are still considered valid. Only variants of type TypeInvalid are considered invalid.

◆ operator=()

Self& remotemono::RMonoVariant::operator= ( const Self other)
inline

Assignment operator.

◆ out()

Self remotemono::RMonoVariant::out ( ) const
inline

Return a DirectionOut alias of this object.

◆ setAutoUnboxEnabled()

void remotemono::RMonoVariant::setAutoUnboxEnabled ( bool  autoUnbox)
inline

Enable or disable automatic unboxing of boxed value type objects.

◆ updateFromRemoteMemory()

template<typename ABI >
void remotemono::RMonoVariant::updateFromRemoteMemory ( ABI &  abi,
RMonoAPIBase mono,
void *  buf 
)

Updates this variant's value from the given buffer as it may be obtained from remote memory.

Parameters
abiThe ABI to use for converting the value.
monoThe Mono API to be used, e.g. for creating RMonoObjectHandle instances.
bufThe buffer to read the raw data from.

The documentation for this class was generated from the following files: