LabWindows/CVI

Sample Code for Calling .NET Assemblies

The following sections of code show a sample .NET assembly written in both Microsoft Visual C# and Microsoft Visual Basic .NET. The sections also include sample code for calling the .NET assembly in Visual C#, Visual Basic .NET, and LabWindows/CVI. Click the arrow next to the section heading to view the sample code.

Sample .NET Assembly Written in Visual C#

// Namespace
namespace MyNamespace
{

// Enumerations
public enum MyEnum1 { MyValue1, MyValue2, MyValue3 }
public enum MyEnum2 { MyValue1, MyValue2 }

// Class definition
public class MyClass1
{

// Constructors
public MyClass1() { }
public MyClass1(string s) { }

// Instance methods
public double MyMethod(int i) { return System.Convert.ToDouble(i); }

public string MyStringMethod(string strIn, out string strOut, ref string strRef)
{

string strReturnValue = strRef;
strRef = strIn;
strOut = strIn + strReturnValue;
return strReturnValue;

}

public double[] MyArrayMethod(string[] arrayIn, out float[] arrayOut, ref string[] arrayRef)
{

arrayRef = arrayIn;
arrayOut = new float[] { 0.0F, 1.0F };
return new double [] { 0.0, 1.0 };

}

public MyStruct MyObjectMethod(MyDerivedClass objIn, out MyBaseClass objOut, ref MyInterface objRef)
{

objOut = objIn;
objRef = objIn;
MyStruct result = new MyStruct();
result.Field1 = 1;
result.Field2 = 2.0;
result.Field3 = "abc";
return result;

}

public MyEnum2 MyEnumMethod(MyEnum1 enumIn, out MyEnum1 enumOut, ref MyEnum1 enumRef)
{

enumOut = enumRef;
enumRef = enumIn;
return MyEnum2.MyValue2;

}

public T MyGenericMethod<T, S>(T tIn, S sIn) { return tIn; }

// Static method
public static void MyStaticMethod() { }

// Instance properties
public int MyReadWriteProperty
{

get { return MyField; }
set { MyField = value;}

}

public int MyReadOnlyProperty
{

get { return MyField; }

}

public int MyWriteOnlyProperty
{

set { MyField = value;}

}

// Static property
public static int MyStaticProperty
{

get { return MyStaticField; }
set { MyStaticField = value;}

}

// Instance field
public int MyField;

// Static field
public static int MyStaticField;

// Nested class
public class MyNestedClass
{

public MyNestedClass() { }

}

}

// Struct definition
public struct MyStruct
{

public int Field1;
public double Field2;
public string Field3;

}

// Interface definition
public interface MyInterface
{

void InterfaceFunc();

}

// Base class
public class MyBaseClass
{

public void BaseClassFunc() { }

}

// Derived class
public class MyDerivedClass : MyBaseClass, MyInterface
{

public void InterfaceFunc() { }

}

// Generic class
public class MyGenericClass<T, S>
{

public MyGenericClass() { }

public int MyMethod(T tIn) { return 0; }
public S MyGenericMethod<M>(M mIn) { return _s; }

public T Type1
{

get { return _t; }
set { _t = value; }

}

public S Type2
{

get { return _s; }
set { _s = value; }

}

private T _t;
private S _s;

}

}

Sample .NET Assembly Written in Visual Basic .NET

Namespace MyNamespace

' Enumerations
Public Enum MyEnum1

MyValue1
MyValue2
MyValue3

End Enum

Public Enum MyEnum2

MyValue1
MyValue2

End Enum

' Class definition
Public Class MyClass1

' Constructors
Public Sub New()
End Sub

Public Sub New(ByVal s As String)
End Sub

' Instance methods
Public Function MyMethod(ByVal i As Integer) As Double

Return System.Convert.ToDouble(i)

End Function

Public Function MyStringMethod(ByVal strIn As String, ByRef strOut As String, ByRef strRef As String) As String

Dim strReturnValue As String = strRef
strRef = strIn
strOut = (strIn + strReturnValue)
Return strReturnValue

End Function

Public Function MyArrayMethod(ByVal arrayIn() As String, ByRef arrayOut() As Single, ByRef arrayRef() As String) As Double()

arrayRef = arrayIn
arrayOut = New Single() {0.0!, 1.0!}
Return New Double() {0, 1}

End Function

Public Function MyObjectMethod(ByVal objIn As MyDerivedClass, ByRef objOut As MyBaseClass, ByRef objRef As MyInterface) As MyStruct

objOut = objIn
objRef = objIn
Dim result As MyStruct = New MyStruct
result.Field1 = 1
result.Field2 = 2
result.Field3 = "abc"
Return result

End Function

Public Function MyEnumMethod(ByVal enumIn As MyEnum1, ByRef enumOut As MyEnum1, ByRef enumRef As MyEnum1) As MyEnum2

enumOut = enumRef
enumRef = enumIn
Return MyEnum2.MyValue2

End Function

Public Function MyGenericMethod(Of T, S)(ByVal tIn As T, ByVal sIn As S) As T

Return tIn

End Function

' Static method
Public Shared Sub MyStaticMethod()
End Sub

' Instance properties
Public Property MyReadWriteProperty() As Integer

Get
   Return MyField
End Get
Set(ByVal Value As Integer)
   MyField = Value
End Set

End Property

Public ReadOnly Property MyReadOnlyProperty() As Integer

Get
   Return MyField
End Get

End Property

Public WriteOnly Property MyWriteOnlyProperty() As Integer

Set(ByVal Value As Integer)
   MyField = Value
End Set

End Property

' Static property
Public Shared Property MyStaticProperty() As Integer

Get
   Return MyStaticField
End Get
Set(ByVal Value As Integer)
   MyStaticField = Value
End Set

End Property

' Instance field
Public MyField As Integer

' Static field
Public Shared MyStaticField As Integer

' Nested class
Public Class MyNestedClass

Public Sub New()
   MyBase.New()
End Sub

End Class

End Class

' Structure definition
Public Structure MyStruct

Public Field1 As Integer
Public Field2 As Double
Public Field3 As String

End Structure

' Interface definition
Public Interface MyInterface

Sub InterfaceFunc()

End Interface

' Base class definition
Public Class MyBaseClass

Public Sub BaseClassFunc()
End Sub

End Class

' Derived class definition
Public Class MyDerivedClass

Inherits MyBaseClass
Implements MyInterface

Public Sub InterfaceFunc() Implements MyInterface.InterfaceFunc
End Sub

End Class

' Generic class
Public Class MyGenericClass(Of T, S)

Public Sub New()
End Sub

Public Function MyMethod(ByVal tIn As T) As Integer

Return 0

End Function

Public Function MyGenericMethod(Of M)(ByVal mIn As M) As S

Return _s

End Function

Public Property Type1() As T

Get

Return _t

End Get

Set(ByVal Value As T)

_t = Value

End Set

End Property

Public Property Type2() As S

Get

Return _s

End Get

Set(ByVal Value As S)

_s = Value

End Set

End Property

Private _t As T

Private _s As S

End Class

End Namespace

Sample Code for Calling the Assembly in Visual C#

//---------------------------------------------------------------------------------
// Creating objects
MyNamespace.MyClass1 obj1 = new MyNamespace.MyClass1();
MyNamespace.MyClass1 obj2 = new MyNamespace.MyClass1("hello");
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Calling instance methods
obj1.MyMethod(0);

string strOut, strRef = "abc";
string strReturnValue = obj1.MyStringMethod("xyz", out strOut, ref strRef);

float[] arrayOut;
string[] arrayRef = new string[] { "X", "Y", "Z" };
double[] arrayReturnValue = obj1.MyArrayMethod(
   new string[] { "a", "b" }, out arrayOut, ref arrayRef);

MyNamespace.MyBaseClass objOut;
MyNamespace.MyInterface objRef = null;
MyNamespace.MyStruct objReturnValue = obj1.MyObjectMethod(
   new MyNamespace.MyDerivedClass(), out objOut, ref objRef);

// Creating a .NET list containing strings
System.Collections.ArrayList stringList = new System.Collections.ArrayList(arrayRef);

// Iterating through a collection using IEnumerator
foreach (string s in stringList)
   Console.WriteLine(s);

// Iterating through a collection using indexer
for (int i = 0; i < stringList.Count; ++i)
   Console.WriteLine((string) stringList[i]);

MyNamespace.MyEnum1 enumOut, enumRef = MyNamespace.MyEnum1.MyValue2;
MyNamespace.MyEnum2 enumReturnValue = obj1.MyEnumMethod(
   MyNamespace.MyEnum1.MyValue1, out enumOut, ref enumRef);

//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Calling static method
MyNamespace.MyClass1.MyStaticMethod();
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Instance properties
int property = obj1.MyReadWriteProperty;
obj1.MyReadWriteProperty = 2;

property = obj1.MyReadOnlyProperty;
obj1.MyWriteOnlyProperty = 3;
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Static property
MyNamespace.MyClass1.MyStaticProperty = 4;
property = MyNamespace.MyClass1.MyStaticProperty;
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Instance field
int field = obj1.MyField;
obj1.MyField = field + 1;
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Static field
MyNamespace.MyClass1.MyStaticField = field;
field = MyNamespace.MyClass1.MyStaticField;
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Creating structure
MyNamespace.MyStruct structure;

// Accessing structure fields
structure.Field1 = 1;
structure.Field2 = 3.1415;
structure.Field3 = "hello";
field = structure.Field1;
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Nested class
MyNamespace.MyClass1.MyNestedClass obj3 = new MyNamespace.MyClass1.MyNestedClass();
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Inheritance
MyNamespace.MyDerivedClass derObj = new MyNamespace.MyDerivedClass();
derObj.BaseClassFunc();
derObj.InterfaceFunc();
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Calling generic method of non-generic class
int result = obj1.MyGenericMethod<int, string>(1, "Hi");
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
// Creating and using generic class
MyNamespace.MyGenericClass<int, string> genObj = new MyNamespace.MyGenericClass<int, string>();
genObj.Type1 = 1;
genObj.Type2 = "Hi";
int intVal = genObj.Type1;
string strVal = genObj.Type2;
intVal = genObj.MyMethod(2);
strVal = genObj.MyGenericMethod<double>(1.1);
//---------------------------------------------------------------------------------

Sample Code for Calling the Assembly in Visual Basic .NET

'----------------------------------------------------------------------------------
' Creating objects
Dim obj1 As MyNamespace.MyClass1 = New MyNamespace.MyClass1
Dim obj2 As MyNamespace.MyClass1 = New MyNamespace.MyClass1("hello")
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Calling instance methods
obj1.MyMethod(0)

Dim strOut, strRef, strReturnValue As String
strRef = "abc"
strReturnValue = obj1.MyStringMethod("xyz", strOut, strRef)

Dim arrayOut As Single()
Dim arrayRef As String() = New String() {"X", "Y", "Z"}
Dim arrayReturnValue As Double()
arrayReturnValue = obj1.MyArrayMethod(New String() {"a", "b"}, arrayOut, arrayRef)

' Creating a .NET list containing strings
Dim stringList As System.Collections.ArrayList = New System.Collections.ArrayList(arrayRef)

' Iterating through a collection using IEnumerator
For Each s As String In stringList
   Console.WriteLine(s)
Next

'Iterating through a collection using indexer
For i As Integer = 1 To stringList.Count
   Console.WriteLine(stringList(i - 1))
Next

Dim objOut As MyNamespace.MyBaseClass
Dim objRef As MyNamespace.MyInterface = Nothing
Dim objReturnValue As MyNamespace.MyStruct
objReturnValue = obj1.MyObjectMethod(New MyNamespace.MyDerivedClass, objOut, objRef)

Dim enumOut, enumRef As MyNamespace.MyEnum1
enumRef = MyNamespace.MyEnum1.MyValue2
Dim enumReturnValue As MyNamespace.MyEnum2
enumReturnValue = obj1.MyEnumMethod(MyNamespace.MyEnum1.MyValue1, enumOut, enumRef)
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Calling static method
MyNamespace.MyClass1.MyStaticMethod()
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Instance properties
Dim property1 As Integer = obj1.MyReadWriteProperty
obj1.MyReadWriteProperty = 2

property1 = obj1.MyReadOnlyProperty
obj1.MyWriteOnlyProperty = 3
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Static property
MyNamespace.MyClass1.MyStaticProperty = 4
property1 = MyNamespace.MyClass1.MyStaticProperty
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Instance field
Dim field As Integer = obj1.MyField
obj1.MyField = field + 1
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Static field
MyNamespace.MyClass1.MyStaticField = field
field = MyNamespace.MyClass1.MyStaticField
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Creating structure
Dim structure1 As MyNamespace.MyStruct

' Accessing structure fields
structure1.Field1 = 1
structure1.Field2 = 3.1415
structure1.Field3 = "hello"
field = structure1.Field1
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Nested class
Dim obj3 As MyNamespace.MyClass1.MyNestedClass = New MyNamespace.MyClass1.MyNestedClass
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Inheritance
Dim derObj As MyNamespace.MyDerivedClass = New MyNamespace.MyDerivedClass
derObj.BaseClassFunc()
derObj.InterfaceFunc()
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Calling generic method of non-generic class
Dim result As Integer = obj1.MyGenericMethod(Of Integer, String)(1, "Hi")
'----------------------------------------------------------------------------------

'----------------------------------------------------------------------------------
' Creating and using generic class
Dim genObj As MyNamespace.MyGenericClass(Of Integer, String) = New MyNamespace.MyGenericClass(Of Integer, String)
genObj.Type1 = 1
genObj.Type2 = "Hi"
Dim intVal As Integer = genObj.Type1
Dim strVal As String = genObj.Type2
intVal = genObj.MyMethod(2)
strVal = genObj.MyGenericMethod(Of Double)(1.1)
'----------------------------------------------------------------------------------

Sample Code for Calling the Assembly in LabWindows/CVI

Note Note  If you generate wrappers for a generic type constructor or a generic method, LabWindows/CVI includes additional string parameters for passing the generic type arguments in the form of .NET type names. Any parameters of the specialized types are typed as void  * in the generated wrapper. Always pass the values for these parameters by reference. The .NET code void Foo<T>(T t) is wrapped as Foo (..., char *T, void *t). The user must pass the value for t by reference. For example, Foo<int>(10) in .NET becomes the following code in C: int t = 10; Foo(..., "System.Int32", &t);.

#include <ansi_c.h>
#include <mscorlib.h>      // NOTE - for using ArrayList and IEnumerator
#include <MyAssembly.h>

void main(void)
{

//-----------------------------------------------------------------------------
// Variable declarations
MyNamespace_MyClass1                obj1, obj2;
int                                 i, arrayOutLength, arrayRefLength,
                                    arrayReturnValueLength, result, intVal,
                                    property, field, notEmpty, nItems;
char                                * strOut, * strRef, * strReturnValue,
                                    * arrayIn[] = { "a", "b" },
                                    ** arrayRef;
float                               * arrayOut;
double                              * arrayReturnValue, dblVal;
MyNamespace_MyBaseClass             objOut;
MyNamespace_MyInterface             objRef = 0;
MyNamespace_MyEnum1                 enumOut,
                                    enumRef = MyNamespace_MyEnum1_MyValue2;
MyNamespace_MyEnum2                 enumReturnValue;
MyNamespace_MyStruct                structure, objReturnValue;
MyNamespace_MyClass1_MyNestedClass  obj3;
MyNamespace_MyDerivedClass          objIn, derObj;
System_Collections_ArrayList        stringList;
System_Collections_IEnumerator      enumerator;
MyNamespace_MyGenericClass_T2       genObj;
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// NOTE - must call the Initialize function before calling other functions
Initialize_MyAssembly();
Initialize_mscorlib();
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Creating objects
MyNamespace_MyClass1__Create(&obj1, 0);
MyNamespace_MyClass1__Create_1(&obj2, "hello", 0);

// NOTE - object handles must be discarded after use by calling CDotNetDiscardHandle
CDotNetDiscardHandle(obj2);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Calling instance methods
MyNamespace_MyClass1_MyMethod(obj1, 0, 0, 0);

// NOTE - Reference arguments must be allocated using CDotNetAllocateMemory
strRef = CDotNetAllocateMemory(sizeof(char) * (strlen("abc") + 1));
strcpy(strRef, "abc");
MyNamespace_MyClass1_MyStringMethod(obj1, "xyz", &strOut, &strRef, &strReturnValue, 0);
// NOTE - Output, return value, and reference arguments that are strings, arrays,
// or object handles must be disposed after use
CDotNetFreeMemory(strOut);
CDotNetFreeMemory(strRef);
CDotNetFreeMemory(strReturnValue);

// NOTE - Reference arguments must be allocated using CDotNetAllocateMemory
arrayRefLength = 3;
arrayRef = CDotNetAllocateMemory(sizeof(char *) * 3);
arrayRef[0] = CDotNetAllocateMemory(sizeof(char) * 2);
strcpy(arrayRef[0], "X");
arrayRef[1] = CDotNetAllocateMemory(sizeof(char) * 2);
strcpy(arrayRef[1], "Y");
arrayRef[2] = CDotNetAllocateMemory(sizeof(char) * 2);
strcpy(arrayRef[2], "Z");

MyNamespace_MyClass1_MyArrayMethod(obj1, arrayIn, sizeof(arrayIn) / sizeof(arrayIn[0]), &arrayOut, &arrayOutLength, &arrayRef, &arrayRefLength, &arrayReturnValue, &arrayReturnValueLength, 0);

// Creating a .NET list containing strings
System_Collections_ArrayList__Create(&stringList, 0);
for (i = 0; i < arrayRefLength; ++i)
{

CDotNetHandle handle;
CDotNetConvertValueToHandle(arrayRef[i], CDOTNET_STRING, &handle);
System_Collections_ArrayList_Add(stringList, handle, 0, 0);
CDotNetDiscardHandle(handle);

}

// Iterating through a collection using IEnumerator (for-each)
System_Collections_ArrayList_GetEnumerator(stringList, &enumerator, 0);
System_Collections_IEnumerator_MoveNext(enumerator, &notEmpty, 0);
while (notEmpty)
{

CDotNetHandle handle;
char * str;
System_Collections_IEnumerator_Get_Current(enumerator, &handle, 0);
CDotNetConvertHandleToValue(handle, CDOTNET_STRING, &str);
printf("%s\n", str);
CDotNetFreeMemory(str);
CDotNetDiscardHandle(handle);
System_Collections_IEnumerator_MoveNext(enumerator, &notEmpty, 0);

}
CDotNetDiscardHandle(enumerator);

// Iterating through a collection using indexer
System_Collections_ArrayList_Get_Count(stringList, &nItems, 0);
for (i = 0; i < nItems; ++i)
{

CDotNetHandle handle;
char * str;
System_Collections_ArrayList_Get_Item(stringList, i, &handle, 0);
CDotNetConvertHandleToValue(handle, CDOTNET_STRING, &str);
printf("%s\n", str);
CDotNetFreeMemory(str);
CDotNetDiscardHandle(handle);

}

CDotNetDiscardHandle(stringList);

// NOTE - Output, return value, and reference arguments that are strings, arrays,
// or object handles must be disposed after use
CDotNetFreeMemory(arrayOut);
for (i = 0; i < arrayRefLength; ++i)

CDotNetFreeMemory(arrayRef[i]);

CDotNetFreeMemory(arrayRef);
CDotNetFreeMemory(arrayReturnValue);

MyNamespace_MyDerivedClass__Create(&objIn, 0);
MyNamespace_MyClass1_MyObjectMethod(obj1, objIn, &objOut, &objRef, &objReturnValue, 0);
CDotNetDiscardHandle(objIn);
// NOTE - Output, return value, and reference arguments that are strings, arrays,
// or object handles must be disposed after use
CDotNetDiscardHandle(objOut);
CDotNetDiscardHandle(objRef);
CDotNetDiscardHandle(objReturnValue);

MyNamespace_MyClass1_MyEnumMethod(obj1, MyNamespace_MyEnum1_MyValue1, &enumOut, &enumRef, &enumReturnValue, 0);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Calling static method
MyNamespace_MyClass1_MyStaticMethod(0);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Instance properties
MyNamespace_MyClass1_Get_MyReadWriteProperty(obj1, &property, 0);
MyNamespace_MyClass1_Set_MyReadWriteProperty(obj1, 2, 0);

MyNamespace_MyClass1_Get_MyReadOnlyProperty(obj1, &property, 0);
MyNamespace_MyClass1_Set_MyWriteOnlyProperty(obj1, 3, 0);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Static property
MyNamespace_MyClass1_Set_MyStaticProperty(4, 0);
MyNamespace_MyClass1_Get_MyStaticProperty(&property, 0);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Instance field
MyNamespace_MyClass1__Get__MyField(obj1, &field, 0);
MyNamespace_MyClass1__Set__MyField(obj1, field + 1, 0);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Static field
MyNamespace_MyClass1__Set__MyStaticField(field, 0);
MyNamespace_MyClass1__Get__MyStaticField(&field, 0);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Creating structure
MyNamespace_MyStruct__Create(&structure, 0);

// Accessing structure fields
MyNamespace_MyStruct__Set__Field1(structure, 1, 0);
MyNamespace_MyStruct__Set__Field2(structure, 3.1415, 0);
MyNamespace_MyStruct__Set__Field3(structure, "hello", 0);
MyNamespace_MyStruct__Get__Field1(structure, &field, 0);

// NOTE - object handles must be discarded after use by calling CDotNetDiscardHandle
CDotNetDiscardHandle(structure);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Nested class
MyNamespace_MyClass1_MyNestedClass__Create(&obj3, 0);
CDotNetDiscardHandle(obj3);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Inheritance
MyNamespace_MyDerivedClass__Create(&derObj, 0);
MyNamespace_MyDerivedClass_BaseClassFunc(derObj, 0);
MyNamespace_MyDerivedClass_InterfaceFunc(derObj, 0);
// NOTE - can also call the wrapper functions in base class or interface
// with type cast to CDotNetHandle or the base class/interface type
MyNamespace_MyBaseClass_BaseClassFunc((CDotNetHandle)derObj, 0);
MyNamespace_MyInterface_InterfaceFunc((MyNamespace_MyInterface)derObj, 0);
CDotNetDiscardHandle(derObj);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Calling generic method of non-generic class
intVal = 1;
MyNamespace_MyClass1_MyGenericMethod(obj1, "System.Int32", "System.String", &intVal, "Hi", &result, 0);
//-----------------------------------------------------------------------------

// NOTE - object handles must be discarded after use by calling CDotNetDiscardHandle
CDotNetDiscardHandle(obj1);

//-----------------------------------------------------------------------------
// Creating and using generic class
MyNamespace_MyGenericClass_T2__Create(&genObj, "System.Int32", "System.String", 0);
MyNamespace_MyGenericClass_T2_Set_Type1(genObj, &intVal, 0);
strRef = "Hi";
MyNamespace_MyGenericClass_T2_Set_Type2(genObj, &strRef, 0);
MyNamespace_MyGenericClass_T2_Get_Type1(genObj, &intVal, 0);
MyNamespace_MyGenericClass_T2_Get_Type2(genObj, &strOut, 0);
CDotNetFreeMemory(strOut);
intVal = 2;
MyNamespace_MyGenericClass_T2_MyMethod(genObj, &intVal, &result, 0);
dblVal = 1.1;
MyNamespace_MyGenericClass_T2_MyGenericMethod(genObj, "System.Double", &dblVal, &strOut, 0);
CDotNetDiscardHandle(genObj);
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// NOTE - must call the Close function to fully clean up the .NET controller
Close_MyAssembly();
Close_mscorlib();
//-----------------------------------------------------------------------------

}