# winim/clr

Dark Mode

- Github Page
- winim
- winstr
- utils
- com
- clr

This module add Windows Common Language Runtime (CLR) support to Winim. So that we can use Nim to interact with Windows .NET frameworks.

This module heavily dependent on `winim/com` module. So please also read the document about it to help understanding the usage. Notice: `int` will be converted into `int32` before passing to CLR even in 64-bit environment.

Example:

    import winim/clr
    proc example1() =
      ## Create a CLR object (aka. C# instance) and call the method
      var mscor = load("mscorlib")
      var rand = mscor.new("System.Random")
      echo rand.Next()

    proc example2() =
      ## Create a type object and call the static method
      var mscor = load("mscorlib")
      var Int32 = mscor.GetType("System.Int32")
      echo @Int32.Parse("12345")

    proc example3() =
      ## Compile some code and run it
      var code = """

        using System;
        public class Test {
          public void Hello() {
            Console.WriteLine("Hello, world");
          }
        }
        """
      var res = compile(code)
      var o = res.CompiledAssembly.new("Test")
      o.Hello()

# Types

    CLRError = object of CatchableError
      hresult*: HRESULT

  Raised if a CLR error occurred.

    CLRInterface = object
      obj*: CLRVariant
      intf*: CLRVariant

  Represent CLR object with specified interface. Use `{}` to create interface object.

    CLRType = distinct variant

  `distinct variant` to represent CLR Type object.

    CLRVariant = distinct variant

  `distinct variant` to represent CLR object or value.

# Consts

    CSharpCodeProvider = "Microsoft.CSharp.CSharpCodeProvider"

    VBCodeProvider = "Microsoft.VisualBasic.VBCodeProvider"

# Procs

    proc `$`(v: CLRVariant): string {....raises: [Exception, ValueError, CLRError,
        VariantConversionError], tags: [RootEffect].}

  `$` operator for CLRVariant.

    proc `==`(x, y: CLRVariant): bool {.borrow, ...raises: [], tags: [].}

  Checks for equality between two `CLRVariant` variables.

    proc `@`(v: CLRVariant): CLRType {....raises: [Exception, ValueError, CLRError],
                                       tags: [RootEffect].}

  Convert `CLRVariant` into `CLRType` so that static members can be invoked.

    proc `[]`(v: CLRVariant; i: SomeOrdinal): CLRVariant

  Index operator for `CLRVariant` (via `IList` interface).

    proc `[]`(v: CLRVariant; name: string): CLRVariant {.
        ...raises: [ValueError, CLRError, Exception, VariantConversionError],
        tags: [RootEffect].}

  Returns specified field as `CLRVariant` from CLR struct type.

    proc `[]`[T: variant | SomeNumber | string](x: T): CLRVariant

  Syntax sugar for x.toObject().

    proc `[]`[T](x: T; typ: CLRVariant): CLRVariant {.inline.}

  Syntax sugar for x.toObject(CLRVariant).

    proc `{}`(v, i: CLRVariant): CLRInterface {.inline, ...raises: [], tags: [].}

  Syntax suger to create CLRInterface (require nim compiler version >= 1.2.0).

    proc clrStart(version = ""): CLRVariant {.discardable,
        ...raises: [Exception, ValueError, CLRError, VariantConversionError],
        tags: [RootEffect].}

  Start the specified CLR and return its `AppDomain`. This call can be omitted if last version of runtime is required.

    proc com(v: CLRVariant): com {....raises: [Exception, ValueError, CLRError],
                                   tags: [RootEffect].}

  Convert `CLRVariant` to winim's com object, aka. COM callable wrapper (CCW).

    proc compile(code: string; references: openArray[string] = ["System.dll"];
                 filename = ""; compilerOptions = ""; provider = CSharpCodeProvider;
                 debug = false): CLRVariant {.discardable,
        ...raises: [Exception, ValueError, CLRError, VariantConversionError],
        tags: [RootEffect].}

  Compiles the specified code. Returns the `CompilerResults` object.

    proc fromCLRVariant[T](x: CLRVariant): T {.inline.}

  Converts a `CLRVariant` into any supported types.

    proc invoke(v: CLRInterface; name: string; flags: int;
                vargs: varargs[CLRVariant, toCLRVariant]): CLRVariant {.discardable,
        ...raises: [ValueError, CLRError, Exception, VariantConversionError],
        tags: [RootEffect].}

  Low level `invoke` for `CLRInterface`.

    proc invoke(v: CLRType; name: string; flags: int;
                vargs: varargs[CLRVariant, toCLRVariant]): CLRVariant {.discardable,
        ...raises: [ValueError, CLRError, Exception, VariantConversionError],
        tags: [RootEffect].}

  Low level `invoke` for `CLRType`. Equal to `CLRType.InvokeMember(...)`

    proc invoke(v: CLRVariant; name: string; flags: int;
                vargs: varargs[CLRVariant, toCLRVariant]): CLRVariant {.discardable,
        ...raises: [ValueError, CLRError, Exception, VariantConversionError],
        tags: [RootEffect].}

  Low level `invoke` for `CLRVariant`. Equal to `CLRVariant.GetType().InvokeMember(...)`

    proc isNil(x: CLRType): bool {.borrow, ...raises: [], tags: [].}

  Check if `CLRType` is nil or not.

    proc isNil(x: CLRVariant): bool {.borrow, ...raises: [], tags: [].}

  Check if `CLRVariant` is nil or not.

    proc isNull(x: CLRVariant): bool {.borrow, ...raises: [], tags: [].}

  Check if `CLRVariant` is C# null or VB nothing.

    proc isObject(v: CLRVariant): bool {....raises: [Exception], tags: [RootEffect].}

  Check if `CLRVariant` is CLR object or not.

    proc isStruct(v: CLRVariant): bool {.inline, ...raises: [], tags: [].}

  Check if `CLRVariant` is CLR struct type (returnd from CLR as VT_RECORD variant).

    proc isType(v: CLRVariant): bool {....raises: [Exception], tags: [RootEffect].}

  Check if `CLRVariant` is CLR Type object or not.

    proc load(data: COMBinary): CLRVariant {.discardable,
        ...raises: [Exception, ValueError, CLRError, VariantConversionError],
        tags: [RootEffect].}

  Loads the assembly with a common object file format (COFF)-based image.

    proc load(data: openArray[byte]): CLRVariant {.discardable,
        ...raises: [Exception, ValueError, CLRError, VariantConversionError],
        tags: [RootEffect].}

  Loads the assembly with a common object file format (COFF)-based image.

    proc load(name: string): CLRVariant {.discardable, ...raises: [Exception,
        ValueError, CLRError, VariantConversionError, ValueError,
        VariantConversionError, Exception, CLRError], tags: [RootEffect].}

  Loads an assembly from file or from the global assembly cache using a partial name.

    proc new(assembly: CLRVariant; name: string;
             vargs: varargs[CLRVariant, toCLRVariant]): CLRVariant {.discardable,
        ...raises: [ValueError, CLRError, Exception, VariantConversionError],
        tags: [RootEffect].}

  Create an instance from this assembly by name (case-sensitive).

    proc new(typ: CLRType; vargs: varargs[CLRVariant, toCLRVariant]): CLRVariant {.
        discardable,
        ...raises: [ValueError, CLRError, Exception, VariantConversionError],
        tags: [RootEffect].}

  Create an instance of this type

    proc reclaim() {....raises: [ValueError, CLRError, Exception,
                              VariantConversionError], tags: [RootEffect].}

  Forces an immediate garbage collection.

    proc repr(v: CLRVariant): string {....raises: [Exception, ValueError, CLRError,
        VariantConversionError], tags: [RootEffect].}

  `repr` operator for CLRVariant.

    proc toCLRVariant(x: typeof(nil)): CLRVariant {.inline, ...raises: [], tags: [].}

  Converts nil into a `CLRVariant`.

    proc toCLRVariant[T](x: openArray[T]; vt: VARENUM = VT_VARIANT): CLRVariant {.
        inline.}

  Converts any supported openArray types into a `CLRVariant`.

    proc toCLRVariant[T](x: T): CLRVariant {.inline.}

  Converts any supported types into a `CLRVariant`.

    proc toObject(x: pointer | proc): CLRVariant

  Converts `pointer` or `proc` into a `System.IntPtr` object.

    proc toObject[T](x: T): CLRVariant

  Try to convert any value types or struct types into a CLR object.

    proc toObject[T](x: T; typ: CLRVariant): CLRVariant

  Try to convert any value types or struct types into CLR object of specified type.

    proc toObject[T](x: T; typ: string): CLRVariant

  Try to convert any value types or struct types into CLR object of specified type.

    proc toVariant(x: CLRVariant): variant {.inline, ...raises: [], tags: [].}

  Converts a `CLRVariant` x into a `variant`.

    proc unwrap(x: CLRVariant): VARIANT {.borrow, ...raises: [], tags: [].}

  Unwrap `CLRVariant` to `VARIANT` object.

# Iterators

    iterator clrVersions(): string {....raises: [Exception, ValueError, CLRError],
                                     tags: [RootEffect].}

  Iterates over every CLR version installed on a computer..

    iterator fieldPairs(v: CLRVariant): tuple[name: string, value: CLRVariant] {.
        ...raises: [ValueError, CLRError, Exception, VariantConversionError],
        tags: [RootEffect].}

  Iterates over every field of CLR struct type returning their name and value.

    iterator fields(v: CLRVariant): string {.
        ...raises: [ValueError, CLRError, Exception], tags: [RootEffect].}

  Iterates over every field of CLR struct type.

    iterator items(v: CLRVariant): CLRVariant {.
        ...raises: [Exception, ValueError, CLRError, VariantConversionError],
        tags: [RootEffect].}

  Iterates over every member of `CLRVariant`. Support System.Array, Enumerable, Collection, etc.

    iterator pairs(v: CLRVariant): (int, CLRVariant) {....raises: [Exception,
        ValueError, CLRError, VariantConversionError, ValueError,
        VariantConversionError, Exception, CLRError, ValueError,
        VariantConversionError, Exception, CLRError], tags: [RootEffect].}

  Iterates over every member of `CLRVariant`. Yields (int, CLRVariant) pairs. Support System.Array, Enumerable, Collection, etc.

# Converters

    converter clrVariantToBool(x: CLRVariant): bool {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `bool` automatically.

    converter clrVariantToChar(x: CLRVariant): char {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `char` automatically.

    converter clrVariantToCOMArray1D(x: CLRVariant): COMArray1D {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `COMArray1D` automatically.

    converter clrVariantToCOMArray2D(x: CLRVariant): COMArray2D {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `COMArray2D` automatically.

    converter clrVariantToCOMArray3D(x: CLRVariant): COMArray3D {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `COMArray3D` automatically.

    converter clrVariantToCOMBinary(x: CLRVariant): COMBinary {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `COMBinary` automatically.

    converter clrVariantToCString(x: CLRVariant): cstring {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `cstring` automatically.

    converter clrVariantToFloat32(x: CLRVariant): float32 {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `float32` automatically.

    converter clrVariantToFloat64(x: CLRVariant): float64 {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `float64` automatically.

    converter clrVariantToInt(x: CLRVariant): int {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `int` automatically.

    converter clrVariantToInt8(x: CLRVariant): int8 {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `int8` automatically.

    converter clrVariantToInt16(x: CLRVariant): int16 {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `int16` automatically.

    converter clrVariantToInt32(x: CLRVariant): int32 {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `int32` automatically.

    converter clrVariantToInt64(x: CLRVariant): int64 {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `int64` automatically.

    converter clrVariantToMString(x: CLRVariant): mstring {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `mstring` automatically.

    converter clrVariantToPointer(x: CLRVariant): pointer {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `ptr IUnknown` automatically.

    converter clrVariantToPtrIDispatch(x: CLRVariant): ptr IDispatch {.
        ...raises: [VariantConversionError, Exception], tags: [RootEffect].}

  Converts `CLRVariant` into `ptr IDispatch` automatically.

    converter clrVariantToPtrIUnknown(x: CLRVariant): ptr IUnknown {.
        ...raises: [VariantConversionError, Exception], tags: [RootEffect].}

  Converts `CLRVariant` into `ptr IUnknown` automatically.

    converter clrVariantToString(x: CLRVariant): string {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `string` automatically.

    converter clrVariantToUint(x: CLRVariant): uint {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `uint` automatically.

    converter clrVariantToUint8(x: CLRVariant): uint8 {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `uint8` automatically.

    converter clrVariantToUInt16(x: CLRVariant): uint16 {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `uint16` automatically.

    converter clrVariantToUInt32(x: CLRVariant): uint32 {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `uint32` automatically.

    converter clrVariantToUInt64(x: CLRVariant): uint64 {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `uint64` automatically.

    converter clrVariantToVariant(x: CLRVariant): variant {....raises: [], tags: [].}

  Converts `CLRVariant` into `variant` automatically.

    converter clrVariantToVARIANTRaw(x: CLRVariant): VARIANT {....raises: [], tags: [].}

  Converts `CLRVariant` into `VARIANT` automatically.

    converter clrVariantToWString(x: CLRVariant): wstring {.
        ...raises: [VariantConversionError], tags: [].}

  Converts `CLRVariant` into `wstring` automatically.

# Macros

    macro `.=`(v: CLRInterface; name: untyped; vargs: varargs[untyped]): untyped

  Dot assignment operator for `CLRInterface`.

    macro `.=`(v: CLRType; name: untyped; vargs: varargs[untyped]): untyped

  Dot assignment operator for `CLRType`. Set a static property or field.

    macro `.=`(v: CLRVariant; name: untyped; vargs: varargs[untyped]): untyped

  Dot assignment operator for `CLRVariant`. Set a property or field.

    macro `.`(v: CLRInterface; name: untyped; vargs: varargs[untyped]): untyped

  Dot operator for `CLRInterface`.

    macro `.`(v: CLRType; name: untyped; vargs: varargs[untyped]): untyped

  Dot operator for `CLRType`. Invoke a static method, get a static property, or get a static field.

    macro `.`(v: CLRVariant; name: untyped; vargs: varargs[untyped]): untyped

  Dot operator for `CLRVariant`. Invoke a method, get a property, or get a field.

    macro clrScript(x: untyped): untyped

  Nim's dot operators `.=` only allow "a.b = c". With this macro, "a.b(c, d) = e" is allowed. Some assignment needs this macro to work.