Interoperability between C# and other languages

Slides:



Advertisements
Similar presentations
Dynamic Memory Allocation in C.  What is Memory What is Memory  Memory Allocation in C Memory Allocation in C  Difference b\w static memory allocation.
Advertisements

Core Java Lecture 4-5. What We Will Cover Today What Are Methods Scope and Life Time of Variables Command Line Arguments Use of static keyword in Java.
C# Language Report By Trevor Adams. Language History Developed by Microsoft Developed by Microsoft Principal Software Architect Principal Software Architect.
Kernighan/Ritchie: Kelley/Pohl:
1 Pointers A pointer variable holds an address We may add or subtract an integer to get a different address. Adding an integer k to a pointer p with base.
Client Side Programming Using Java Applet Outcomes: You will be expected to know: – Java Applets and HTML file; –bytecode and platform independent programs;
ECE 353: Lab C Pointers and Structs. Basics A pointer holds an address to some variable Notation: – Dereferencing operator: * int *x is a declaration.
1 Pointers & functions Pointers allow us to simulate pass by reference. void swap(int &a, int &b) { int temp = a; a = b; b = temp; } int main () { int.
C#.NET C# language. C# A modern, general-purpose object-oriented language Part of the.NET family of languages ECMA standard Based on C and C++
Session 1 CS-240 Data Structures Binghamton University Dick Steflik.
History  We first begin with Java which was released in 1995 by Sun Microsystems  Initially Java was 100% interpreted at runtime and was very slow 
1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation –The new operator –The delete operator –Dynamic.
CMSC 341 Introduction to Java Based on tutorial by Rebecca Hasti at
Java versus C# An introduction to C# and Visual Studio.
Differences between C# and C++ Dr. Catherine Stringfellow Dr. Stewart Carpenter.
Imperative Programming. Heart of program is assignment statements Aware that memory contains instructions and data values Commands: variable declarations,
Java Security. Topics Intro to the Java Sandbox Language Level Security Run Time Security Evolution of Security Sandbox Models The Security Manager.
Introduction to Java Appendix A. Appendix A: Introduction to Java2 Chapter Objectives To understand the essentials of object-oriented programming in Java.
Overview of Previous Lesson(s) Over View  OOP  A class is a data type that you define to suit customized application requirements.  A class can be.
11 Getting Started with C# Chapter Objectives You will be able to: 1. Say in general terms how C# differs from C. 2. Create, compile, and run a.
By Nicholas Policelli An Introduction to Java. Basic Program Structure public class ClassName { public static void main(String[] args) { program statements.
By Noorez Kassam Welcome to JNI. Why use JNI ? 1. You already have significantly large and tricky code written in another language and you would rather.
Introduction to C# C# is - elegant, type-safe, object oriented language enabling to build applications that run on the.NET framework - types of applications.
CS 11 java track: lecture 1 Administrivia need a CS cluster account cgi-bin/sysadmin/account_request.cgi need to know UNIX
Chapter 0.2 – Pointers and Memory. Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile.
The basics of the array data structure. Storing information Computer programs (and humans) cannot operate without information. Example: The array data.
Netprog: Java Intro1 Crash Course in Java. Netprog: Java Intro2 Why Java? Network Programming in Java is very different than in C/C++ –much more language.
C# D1 CSC 298 Elements of C# code (part 2). C# D2 Writing a class (or a struct)  Similarly to Java or C++  Fields: to hold the class data  Methods:
CIT 590 Intro to Programming First lecture on Java.
Software Engineering in Robotics Interfacing to external functions Henrik I. Christensen –
Programming for Beginners Martin Nelson Elizabeth FitzGerald Lecture 15: More-Advanced Concepts.
Applied Computing Technology Laboratory QuickStart C# Learning to Program in C# Amy Roberge & John Linehan November 7, 2005.
ILM Proprietary and Confidential -
Hoang Anh Viet Hà Nội University of Technology Chapter 1. Introduction to C# Programming.
C++ Review (3) Structs, Classes, Data Abstraction.
Fall 2015CISC124 - Prof. McLeod1 CISC124 Have you filled out the lab section survey? (As of last night 54 left to fill out the survey.) TA names have been.
IAP C# and.NET 2011 Lecture 1: Basic Syntax Geza Kovacs.
Session 7 Methods Strings Constructors this Inheritance.
C# C1 CSC 298 Elements of C# code (part 1). C# C2 Style for identifiers  Identifier: class, method, property (defined shortly) or variable names  class,
Bill Campbell, UMB Microsoft's.NET C# and The Common Language Runtime.
Array Objectives To understand the concept of arrays To understand the purpose to which we use arrays. To be able to declare references to arrays. To be.
1 9/6/05CS360 Windows Programming CS360 Windows Programming.
Computer Organization and Design Pointers, Arrays and Strings in C Montek Singh Sep 18, 2015 Lab 5 supplement.
Managing C++ CHRIS DAHLBERG MID-TIER DEVELOPER SCOTTRADE.
Object Oriented Software Development 4. C# data types, objects and references.
Introduction to C# By: Abir Ghattas Michel Barakat.
1 Predefined Classes and Objects Chapter 3. 2 Objectives You will be able to:  Use predefined classes available in the Java System Library in your own.
IAP C# 2011 Lecture 2: Delegates, Lambdas, LINQ Geza Kovacs.
An Introduction to Java – Part 1 Erin Hamalainen CS 265 Sec 001 October 20, 2010.
CS 31 Discussion, Week 7 Faisal Alquaddoomi, Office Hours: BH 2432, W 4:30-6:30pm, F 12:30-1:30pm.
Array and Pointers An Introduction Unit Unit Introduction This unit covers the usage of pointers and arrays in C++
METADATA IN.NET Presented By Sukumar Manduva. INTRODUCTION  What is Metadata ? Metadata is a binary information which contains the complete description.
Java and C# - Some Commonalities Compile into machine-independent, language- independent code which runs in a managed execution environment Garbage Collection.
Value Types. 2 Objectives Discuss concept of value types –efficiency –memory management –value semantics –boxing –unboxing –simple types Introduce struct.
INTRODUCTION BEGINNING C#. C# AND THE.NET RUNTIME AND LIBRARIES The C# compiler compiles and convert C# programs. NET Common Language Runtime (CLR) executes.
Computer Organization and Design Pointers, Arrays and Strings in C
C# for C++ Programmers 1.
C# - OOP TTU IT College , Autumn SEMESTER Andres käver.
Jim Fawcett CSE775 – Distributed Objects Spring 2009
Methods Attributes Method Modifiers ‘static’
Microsoft .NET 3. Language Innovations Pan Wuming 2017.
Jim Fawcett CSE687-OnLine – Object Oriented Design Summer 2017
Introduction to C# AKEEL AHMED.
C# In many ways, C# looks similar to Java
Programming in C# CHAPTER 1
Pointers C#, pointers can only be declared to hold the memory addresses of value types int i = 5; int *p; p = &i; *p = 10; // changes the value of i to.
CSC 497/583 Advanced Topics in Computer Security
Introduction to java Part I By Shenglan Zhang.
Jim Fawcett CSE681 – Software Modeling and Analysis Fall 2006
SPL – PS1 Introduction to C++.
Presentation transcript:

Interoperability between C# and other languages Geza Kovacs

Managed vs Unmanaged Code Code you write in C# (or VB.NET, or F#, etc) is compiled into Common Intermediate Language (CIL) bytecode, which runs on the .NET framework (managed code) Code you write in C or C++ is compiled into machine code which runs directly on the machine (unmanaged code)

The Win32 API An unmanaged (written in C) library that allows your program to interact with Windows system services Ex: GetVersion() function in the Win32 API determines the version of Windows: // from windows.h DWORD WINAPI GetVersion();

The Win32 API An unmanaged (written in C) library that allows your program to interact with Windows system services Ex: GetVersion() function in the Win32 API determines the version of Windows: // from windows.h DWORD WINAPI GetVersion(); Equivalent to unsigned int __stdcall GetVersion();

stdcall calling convention The Win32 API An unmanaged (written in C) library that allows your program to interact with Windows system services Ex: GetVersion() function in the Win32 API determines the version of Windows: // from windows.h DWORD WINAPI GetVersion(); Equivalent to unsigned int __stdcall GetVersion(); stdcall calling convention

P/Invoke (Platform Invoke) We can make functions from unmanaged code available to our C# program using P/Invoke [DllImport("kernel32.dll")] static extern uint GetVersion(); GetVersion() function is implemented in kernel32.dll // from windows.h DWORD WINAPI GetVersion(); Equivalent to unsigned int __stdcall GetVersion();

P/Invoke (Platform Invoke) We can make functions from unmanaged code available to our C# program using P/Invoke [DllImport("kernel32.dll")] static extern uint GetVersion(); // from windows.h DWORD WINAPI GetVersion(); Equivalent to “uint” in C# is equivalent to C datatype “unsigned int” unsigned int __stdcall GetVersion();

P/Invoke (Platform Invoke) We can make functions from unmanaged code available to our C# program using P/Invoke using System; using System.Runtime.InteropServices; static class MyMainClass { [DllImport("kernel32.dll")] static extern uint GetVersion(); static void Main(string[] args) uint winver = GetVersion(); } // from windows.h DWORD WINAPI GetVersion(); Equivalent to unsigned int __stdcall GetVersion();

// from windows.h DWORD WINAPI GetVersion(); Equivalent to unsigned int __stdcall GetVersion(); using System; using System.Runtime.InteropServices; static class MyMainClass { [DllImport("kernel32.dll")] static extern uint GetVersion(); static void Main(string[] args) uint winver = GetVersion(); uint majorv = winver & 0xFF; uint minorv = (winver & 0xFF00) >> 8; Console.WriteLine("Windows version: " + majorv + "." + minorv); }

// from windows.h DWORD WINAPI GetVersion(); Equivalent to unsigned int __stdcall GetVersion(); using System; using System.Runtime.InteropServices; static class MyMainClass { [DllImport("kernel32.dll", EntryPoint="GetVersion")] static extern uint getver(); static void Main(string[] args) uint winver = getver(); uint majorv = winver & 0xFF; uint minorv = (winver & 0xFF00) >> 8; Console.WriteLine("Windows version: " + majorv + "." + minorv); } If importing a function under a different name, use EntryPoint to specify the original function name

For many APIs in Win32 like GetVersion(), For many APIs in Win32 like GetVersion(), .NET already provides a wrapper for you (for these you don’t need to use P/Invoke) using System; static class MyMainClass { static void Main(string[] args) Version winver = Environment.OSVersion.Version; int majorv = winver.Major; int minorv = winver.Minor; Console.WriteLine("Windows version: " + majorv + "." + minorv); }

Calling Conventions Calling convention: convention for passing arguments to functions, and cleaning up the stack after the function has exited Libraries part of the Win32 API use the stdcall calling convention Most other libraries and C compilers, however, default to the cdecl calling convention int __stdcall someFunction(int arg); Equivalent to int __cdecl someFunction(int arg); int someFunction(int arg);

Specifying calling convention Calling convention can be specified using the CallingConvention named argument If not specified, P/Invoke defaults to stdcall [DllImport("kernel32.dll")] static extern uint GetVersion(); Equivalent to [DllImport("kernel32.dll", CallingConvention=CallingConvention.StdCall)] static extern uint GetVersion();

C standard library is implemented in msvcrt.dll When using functions outside the Win32 API (ex: sqrt from the C standard library), cdecl calling convention should be specified Equivalent to // from math.h double sqrt(double x); // from math.h double __cdecl sqrt(double x); C standard library is implemented in msvcrt.dll [DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)] static double sqrt(double num);

When using functions outside the Win32 API (ex: sqrt from the C standard library), cdecl calling convention should be specified Equivalent to // from math.h double sqrt(double x); // from math.h double __cdecl sqrt(double x); using System; using System.Runtime.InteropServices; static class MyMainClass { [DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)] static double sqrt(double num); static void Main(string[] args) double sqrtOfNine = sqrt(9.0); Console.WriteLine(sqrtOfNine); }

C and C++ compilers also default to the cdecl calling convention for functions // fib.h extern "C" __declspec(dllexport) int fib(int n); Compiled to fibonacci.dll // fib.c #include "fib.h" int fib(int n) { if (n == 0 || n == 1) return 1; return fib(n-1) + fib(n-2); } [DllImport("fibonacci.dll", CallingConvention = CallingConvention.Cdecl)] static extern int fib(int n);

C and C++ compilers also default to the cdecl calling convention for functions // fib.h extern "C" __declspec(dllexport) int fib(int n); Compiled to fibonacci.dll // fib.c #include "fib.h" int fib(int n) { if (n == 0 || n == 1) return 1; return fib(n-1) + fib(n-2); } using System; using System.Runtime.InteropServices; static class MyMainClass { [DllImport("fibonacci.dll", CallingConvention = CallingConvention.Cdecl)] static extern int fib(int n); static void Main(string[] args) { Console.WriteLine(fib(8)); }

Pointers An variable that refers to some location in memory Frequently used in C and C++, exists in C# mostly for interoperability purposes int x = 5; int* p; p = &x; Console.WriteLine(*p); p is a pointer to an int

Determines x’s location in memory (address), makes p point to it Pointers An variable that refers to some location in memory Frequently used in C and C++, exists in C# mostly for interoperability purposes int x = 5; int* p; p = &x; Console.WriteLine(*p); Determines x’s location in memory (address), makes p point to it

dererences p (reads memory p points to) Pointers An variable that refers to some location in memory Frequently used in C and C++, exists in C# mostly for interoperability purposes int x = 5; int* p; p = &x; Console.WriteLine(*p); dererences p (reads memory p points to)

Pointers Any location where pointers are used must be marked with the unsafe keyword using System; static class MyMainClass { static void Main(string[] args) unsafe int x = 5; int* p; p = &x; Console.WriteLine(*p); }

Pointers Any location where pointers are used must be marked with the unsafe keyword using System; static class MyMainClass { static unsafe void Main(string[] args) int x = 5; int* p; p = &x; Console.WriteLine((int)p); }

Pointers Any location where pointers are used must be marked with the unsafe keyword using System; static unsafe class MyMainClass { static void Main(string[] args) int x = 5; int* p; p = &x; Console.WriteLine(*p); }

Pointers can be passed to functions using System; static unsafe class MyMainClass { static void swap(int* x, int* y) int t = *y; *y = *x; *x = t; } static void Main(string[] args) int q = 5; int r = 7; swap(&q, &r); Console.WriteLine(q); // 7 Console.WriteLine(r); // 5

Point is a struct (value type) Pointers can refer to value types (like structs) using System; struct Point { public int x, y; } static unsafe class MyMainClass static void Main(string[] args) Point p = new Point(); Point* ptr = &p; Point is a struct (value type)

Pointers can refer to value types (like structs) using System; struct Point { public int x, y; } static unsafe class MyMainClass static void Main(string[] args) Point p = new Point(); Point* ptr = &p; (*ptr).x = 3; (*ptr).y = 5; Console.WriteLine(p.x); // 3 Console.WriteLine(p.y); // 5

ptr->x is a shorthand for (*ptr).x Pointers can refer to value types (like structs) using System; struct Point { public int x, y; } static unsafe class MyMainClass static void Main(string[] args) Point p = new Point(); Point* ptr = &p; ptr->x = 3; ptr->y = 5; Console.WriteLine(p.x); // 3 Console.WriteLine(p.y); // 5 ptr->x is a shorthand for (*ptr).x

Point is a class (reference type) Pointers cannot refer to reference types (like classes) Because the garbage collector might move class instances around using System; class Point { public int x, y; } static unsafe class MyMainClass static void Main(string[] args) Point p = new Point(); Point* ptr = &p; // NOT ALLOWED Point is a class (reference type)

Pointers can refer to fields in structs using System; struct Point { public int x, y; } static unsafe class MyMainClass static void Main(string[] args) Point p = new Point(); int* xPtr = &p.x; *xPtr = 5; Console.WriteLine(p.x);

If referring to a field in a class, use fixed to ensure the class instance doesn’t get moved by the garbage collector using System; class Point { public int x, y; } static unsafe class MyMainClass static void Main(string[] args) Point p = new Point(); fixed (int* xPtr = &p.x) *xPtr = 5; Console.WriteLine(p.x); Garbage collector not allowed to move p while code in fixed block is running

p: pointer to first array element If using pointers to elements of an array, also need to use fixed using System; static unsafe class MyMainClass { static void Main(string[] args) int[] arr = new int[10]; fixed (int* p = &arr[0]) *p = 5; } p: pointer to first array element

If using pointers to elements of an array, also need to use fixed using System; static unsafe class MyMainClass { static void Main(string[] args) int[] arr = new int[10]; fixed (int* p = &arr[0]) *p = 5; } Element at index 0 set to 5

Pointer arithmetic is allowed in C# using System; static unsafe class MyMainClass { static void Main(string[] args) int[] arr = new int[10]; fixed (int* p = &arr[0]) *p = 5; *(p + 1) = 6; } Element at index 1 set to 6

Pointer arithmetic is allowed in C# using System; static unsafe class MyMainClass { static void Main(string[] args) int[] arr = new int[10]; fixed (int* p = &arr[0]) *p = 5; *(p + 1) = 6; *(p + 2) = 8; } Element at index 2 set to 8

Pointer arithmetic is allowed in C# Indexing syntax can also be used: p[i] is equivalent to *(p+i) using System; static unsafe class MyMainClass { static void Main(string[] args) int[] arr = new int[10]; fixed (int* p = &arr[0]) *p = 5; *(p + 1) = 6; p[2] = 8; } Element at index 2 set to 8

static extern double average(double* list, int length); // average.h extern "C" __declspec(dllexport) double average(double *list, int length); // average.c #include "average.h" double average(double *list, int length) { double total = 0.0; for (int i = 0; i < length; ++i) total += list[i]; return total / length; } Compiled to average.dll [DllImport("average.dll", CallingConvention = CallingConvention.Cdecl)] static extern double average(double* list, int length);

Compiled to average.dll // average.h extern "C" __declspec(dllexport) double average(double *list, int length); // average.c #include "average.h" double average(double *list, int length) { double total = 0.0; for (int i = 0; i < length; ++i) total += list[i]; return total / length; } Compiled to average.dll using System; using System.Runtime.InteropServices; static unsafe class MyMainClass { [DllImport("average.dll", CallingConvention = CallingConvention.Cdecl)] static extern double average(double* list, int length); static void Main(string[] args) { double[] arr = new double[] { 2,4,6,8,9,4,6,6,8,6 }; fixed (double* p = &arr[0]) { Console.WriteLine(average(p, arr.Length)); }

C-style string: character array terminated by 0 puts: part of the C standard library, prints a C-style string Note: char in C is 1 byte, char in C# is 2 bytes. Use C# sbyte datatype instead. // from stdio.h int __cdecl puts(char* str); [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] static extern void puts(sbyte* str);

C-style string: character array terminated by 0 puts: part of the C standard library, prints a C-style string Note: char in C is 1 byte, char in C# is 2 bytes. Use C# sbyte datatype instead. // from stdio.h int __cdecl puts(char* str); using System; using System.Runtime.InteropServices; static unsafe class MyMainClass { [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] static extern void puts(sbyte* str); static void Main(string[] args) { sbyte[] msg = new sbyte[] { (sbyte)'h', (sbyte)'i', (sbyte)'!', 0}; fixed (sbyte* p = &msg[0]) { puts(p); }

GetUserName(): Win32 API function that writes the username into the given character buffer BOOL WINAPI GetUserName(LPTSTR lpBuffer, LPDWORD lpnSize); equivalent to bool __stdcall GetUserName(char* buffer, unsigned int* bufferSize); [DllImport("advapi32.dll")] static extern bool GetUserName (sbyte* buffer, uint* bufferSize);

GetUserName(): Win32 API function that writes the username into the given character buffer BOOL WINAPI GetUserName(LPTSTR lpBuffer, LPDWORD lpnSize); equivalent to bool __stdcall GetUserName(char* buffer, unsigned int* bufferSize); using System; using System.Runtime.InteropServices; static unsafe class MyMainClass { [DllImport("advapi32.dll")] static extern bool GetUserName(sbyte* buffer, uint* bufferSize); static void Main(string[] args) { sbyte[] buf = new sbyte[1024]; uint size = 1024; string name; fixed (sbyte* p = &buf[0]) { GetUserName(p, &size); name = new string(p); } Console.WriteLine(name);

a struct in C, with fields x and y // point.h struct Point { int x, y; }; extern "C" __declspec(dllexport) Point addPoints(Point a, Point b); a struct in C, with fields x and y // point.cpp #include "point.h" Point addPoints(Point a, Point b) { Point c; c.x = a.x + b.x; c.y = a.y + b.y; return c; } Compiled to point.dll Can also pass custom C and C++ datatypes (struct, class) using P/Invoke

Need to define a C# struct with same fields // point.h struct Point { int x, y; }; extern "C" __declspec(dllexport) Point addPoints(Point a, Point b); // point.cpp #include "point.h" Point addPoints(Point a, Point b) { Point c; c.x = a.x + b.x; c.y = a.y + b.y; return c; } Compiled to point.dll using System; using System.Runtime.InteropServices; struct Point { public int x, y; } static class MyMainClass { [DllImport("point.dll", CallingConvention=CallingConvention.Cdecl)] static extern Point addPoints(Point a, Point b); static void Main(string[] args) { Point a; Point b; a.x = 4; a.y = 7; b.x = 3; b.y = 9; Point c = addPoints(a, b); } Need to define a C# struct with same fields

a class in C++, with fields x and y // point.h class Point { public: int x, y; }; extern "C" __declspec(dllexport) Point addPoints(Point a, Point b); a class in C++, with fields x and y // point.cpp #include "point.h" Point addPoints(Point a, Point b) { Point c; c.x = a.x + b.x; c.y = a.y + b.y; return c; } Compiled to point.dll using System; using System.Runtime.InteropServices; struct Point { public int x, y; } static class MyMainClass { [DllImport("point.dll", CallingConvention=CallingConvention.Cdecl)] static extern Point addPoints(Point a, Point b); static void Main(string[] args) { Point a; Point b; a.x = 4; a.y = 7; b.x = 3; b.y = 9; Point c = addPoints(a, b); } Pass C++ classes as C# structs, not classes

C++/CLI Often, want to use both libraries written in both managed (C#, VB.NET, F#) and unmanaged code (C, C++) P/Invoke with C# is suboptimal – requires rewriting each signature for each unmanaged function, and rewriting all fields in each unmanaged type Solution: use C++ with a set of extensions allowing managed code to be invoked (C++/CLI)

Hello World in C# vs C++/CLI In C#, everything must be in a class. In C++/CLI, functions outside classes are also allowed using System; static class MyMainClass { static void Main() { Console.WriteLine("hello world"); } using namespace System; int main() { Console::WriteLine("hello world"); } Static methods called with ::

Reference are listed within the C++/CLI file using System; using System.Collections.Generic; static class MyMainClass { static void Main() { LinkedList<int> list = new LinkedList<int>(); for (int i = 0; i < 10; ++i) list.AddLast(i); foreach (int i in list) Console.WriteLine(i); } #using "System.dll" using namespace System; using namespace System::Collections::Generic; int main() { LinkedList<int> ^list = gcnew LinkedList<int>(); for (int i = 0; i < 10; ++i) list->AddLast(i); for each (int i in list) Console::WriteLine(i); } Reference are listed within the C++/CLI file

Namespace contents accessed via :: using System; using System.Collections.Generic; static class MyMainClass { static void Main() { LinkedList<int> list = new LinkedList<int>(); for (int i = 0; i < 10; ++i) list.AddLast(i); foreach (int i in list) Console.WriteLine(i); } #using "System.dll" using namespace System; using namespace System::Collections::Generic; int main() { LinkedList<int> ^list = gcnew LinkedList<int>(); for (int i = 0; i < 10; ++i) list->AddLast(i); for each (int i in list) Console::WriteLine(i); } Namespace contents accessed via ::

^ is pointer to managed type using System; using System.Collections.Generic; static class MyMainClass { static void Main() { LinkedList<int> list = new LinkedList<int>(); for (int i = 0; i < 10; ++i) list.AddLast(i); foreach (int i in list) Console.WriteLine(i); } #using "System.dll" using namespace System; using namespace System::Collections::Generic; int main() { LinkedList<int> ^list = gcnew LinkedList<int>(); for (int i = 0; i < 10; ++i) list->AddLast(i); for each (int i in list) Console::WriteLine(i); } ^ is pointer to managed type

gcnew used to allocate managed (garbage-collected) types using System; using System.Collections.Generic; static class MyMainClass { static void Main() { LinkedList<int> list = new LinkedList<int>(); for (int i = 0; i < 10; ++i) list.AddLast(i); foreach (int i in list) Console.WriteLine(i); } #using "System.dll" using namespace System; using namespace System::Collections::Generic; int main() { LinkedList<int> ^list = gcnew LinkedList<int>(); for (int i = 0; i < 10; ++i) list->AddLast(i); for each (int i in list) Console::WriteLine(i); } gcnew used to allocate managed (garbage-collected) types

using System.Collections.Generic; static class MyMainClass { static void Main() { LinkedList<int> list = new LinkedList<int>(); for (int i = 0; i < 10; ++i) list.AddLast(i); foreach (int i in list) Console.WriteLine(i); } #using "System.dll" using namespace System; using namespace System::Collections::Generic; int main() { LinkedList<int> ^list = gcnew LinkedList<int>(); for (int i = 0; i < 10; ++i) list->AddLast(i); for each (int i in list) Console::WriteLine(i); } -> used to invoke instance methods :: used to invoke static methods

class Point { public int x; public int y; public Point(int x, int y) { this.x = x; this.y = y; } static class MyMainClass { static void Main() { Point p = new Point(3, 7); Access modifier in C++/CLI is denoted using public: (or private:, etc); applies to all following fields and methods ref class Point { public: int x; int y; Point(int x, int y) { this->x = x; this->y = y; } }; int main() { Point ^p = gcnew Point(3, 7);

ref class is a reference type; corresponds to “class” in C# class Point { public int x; public int y; public Point(int x, int y) { this.x = x; this.y = y; } static class MyMainClass { static void Main() { Point p = new Point(3, 7); ref class is a reference type; corresponds to “class” in C# default access modifier is private ref class Point { public: int x; int y; Point(int x, int y) { this->x = x; this->y = y; } }; int main() { Point ^p = gcnew Point(3, 7); Default private Default public Reference type ref class ref struct Value type value class value struct Unmanaged type class struct

ref struct is also a reference type; also corresponds to “class” in C# class Point { public int x; public int y; public Point(int x, int y) { this.x = x; this.y = y; } static class MyMainClass { static void Main() { Point p = new Point(3, 7); ref struct is also a reference type; also corresponds to “class” in C# default access modifier is public ref struct Point { int x; int y; Point(int x, int y) { this->x = x; this->y = y; } }; int main() { Point ^p = gcnew Point(3, 7); Default private Default public Reference type ref class ref struct Value type value class value struct Unmanaged type class struct

value class is a value type; corresponds to “struct” in C# struct Point { public int x; public int y; public Point(int x, int y) { this.x = x; this.y = y; } static class MyMainClass { static void Main() { Point p = new Point(3, 7); value class is a value type; corresponds to “struct” in C# default access modifier is private value class Point { public: int x; int y; Point(int x, int y) { this->x = x; this->y = y; } }; int main() { Point ^p = gcnew Point(3, 7); Default private Default public Reference type ref class ref struct Value type value class value struct Unmanaged type class struct

value struct is a value type; corresponds to “struct” in C# struct Point { public int x; public int y; public Point(int x, int y) { this.x = x; this.y = y; } static class MyMainClass { static void Main() { Point p = new Point(3, 7); value struct is a value type; corresponds to “struct” in C# default access modifier is public value struct Point { int x; int y; Point(int x, int y) { this->x = x; this->y = y; } }; int main() { Point ^p = gcnew Point(3, 7); Default private Default public Reference type ref class ref struct Value type value class value struct Unmanaged type class struct

Cannot be “ref class” or “value class” class Point { public: int x, y; }; class Vector { Point start, end; A unmanaged class cannot be the field of a managed class Cannot be “ref class” or “value class”

A unmanaged type cannot be the field of a managed class value class Point { public: int x, y; }; value class Vector { Point start, end; A unmanaged type cannot be the field of a managed class A managed type cannot be the field of an unmanaged class can’t be “class”

#include <vcclr.h> ref class Point { public: int x, y; }; class Vector { gcroot<Point^> start; gcroot<Point^> end; Vector() { start = gcnew Point; end = gcnew Point; } int main() { Vector v; v.start->x = 5; v.start->y = 6; gcroot<T> can be used to wrap ref and value types as unmanaged types

Ref and value classes can have pointers to unmanaged classes class Point { public: int x, y; }; ref class Vector { Point *start; Point *end; Vector() { start = new Point; end = new Point; } ~Vector() { delete start; delete end; int main() { Vector^ v = gcnew Vector; v->start->x = 5; v->start->y = 6; gcroot<T> can be used to wrap ref and value types as unmanaged types Ref and value classes can have pointers to unmanaged classes Destructor: gets run when managed type becomes inaccessible destructor

Managed classes should be stored in managed containers (array<T>, System::Collections::Generic::LinkedList<T>) Unmanaged classes should be stored in unmanaged containers (standard array, std::list<T>) ref class ManagedPoint { public: int x, y; }; class Point { int main() { Point* arr = new Point[8]; delete[] arr; array<ManagedPoint^>^ marr = gcnew array<ManagedPoint^>(8); }

Managed classes should be stored in managed containers (array<T>, System::Collections::Generic::LinkedList<T>) Unmanaged classes should be stored in unmanaged containers (standard array, std::list<T>) #using "System.dll" #include <list> using namespace System::Collections::Generic; ref class ManagedPoint { public: int x, y; }; class Point { int main() { std::list<Point> lst; LinkedList<ManagedPoint^>^ mlst = gcnew LinkedList<ManagedPoint^>(); }

Additionally, STL/CLR, an implementation of the STL for managed types, is available in the cliext namespace #using "Microsoft.VisualC.STLCLR.dll" #include <cliext/list> ref class ManagedPoint { public: int x, y; }; int main() { ManagedPoint ^p = gcnew ManagedPoint; p->x = 5; p-> y = 7; cliext::list<ManagedPoint^> ^lst = gcnew cliext::list<ManagedPoint^>; lst->push_back(p); }

class Point { public: int x, y; }; ref class ManagedPoint { ManagedPoint^ addPoints(Point a, ManagedPoint ^b) { ManagedPoint ^c = gcnew ManagedPoint(); c->x = a.x + b->x; c->y = a.y + b->y; return c; } int main() { Point p; p.x = 3; p.y = 5; ManagedPoint ^m = gcnew ManagedPoint(); m->x = 5; m-> y = 8; ManagedPoint ^q = addPoints(p, m); Functions and methods can have both managed and unmanaged types as arguments

class Point { public: int x, y; }; ref class ManagedPoint { Point addPoint(Point a) { Point p; p.x = a.x + x; p.y = a.x + y; return p; } int main() { Point p; p.x = 3; p.y = 5; ManagedPoint ^m = gcnew ManagedPoint(); m->x = 5; m-> y = 8; Point q = m->addPoint(p); Functions and methods can have both managed and unmanaged types as arguments

ref class ManagedPoint { public: int x, y; }; class Point { ManagedPoint^ addPoint(ManagedPoint ^a) { ManagedPoint ^p = gcnew ManagedPoint; p->x = a->x + x; p->y = a->y + y; return p; } int main() { Point p; p.x = 3; p.y = 5; ManagedPoint ^m = gcnew ManagedPoint(); m->x = 5; m-> y = 8; ManagedPoint ^q = p.addPoint(m); Functions and methods can have both managed and unmanaged types as arguments

Delegates are available; can reference: using System; static class MyMainClass { static int square(int x) { return x * x; } static void Main() { Func<int, int> sq = square; Console.WriteLine(sq(4)); Delegates are available; can reference: functions static methods instance methods using namespace System; int square(int x) { return x * x; } int main() { Func<int, int>^ sq = gcnew Func<int, int>(square); Console::WriteLine(sq(4));

Delegates are available; can reference: using System; static class MyMainClass { static int square(int x) { return x * x; } static void Main() { Func<int, int> sq = square; Console.WriteLine(sq(4)); Delegates are available; can reference: functions static methods instance methods using namespace System; ref class Utils { public: static int square(int x) { return x*x; } }; int main() { Func<int, int> ^sq = gcnew Func<int, int>(Utils::square); Console::WriteLine(sq(4));

Delegates are available; can reference: using System; using System.Collections.Generic; static class MyMainClass { static void Main() { HashSet<int> set = new HashSet<int>(); set.Add(5); set.Add(7); Func<int, bool> contains = set.Contains; Console.WriteLine(contains(7)); // True } Delegates are available; can reference: functions static methods instance methods #using "System.dll" #using "System.Core.dll" using namespace System; using namespace System::Collections::Generic; int main() { HashSet<int>^ set = gcnew HashSet<int>(); set->Add(5); set->Add(7); Func<int, bool>^ contains = gcnew Func<int, bool>(set, &HashSet<int>::Contains); Console::WriteLine(contains(7)); // True }

Final notes on C++/CLI C++/CLI also lacks many other syntactic features of C#: Type inference (var) Lambdas Extension methods (need to pass in this argument manually) LINQ (since it consists of extension methods) Hence, generally C++/CLI is used only for wrapping libraries into a managed class to be used in C#

Interop with Java The JVM is similar to the CLR: both are virtual machines on which platform-independent bytecode runs Compiled Java bytecode (.jar files) can be converted into .NET bytecode (assemblies) using IKVM http://www.ikvm.net/ Using IKVM, you can create and use instances of classes defined in Java code within your C# program