Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP

Slides:



Advertisements
Presentazioni simili
Compilazione di Programmi C/C++
Advertisements

Carlo Becchi .NET Tutorial Carlo Becchi
INTRODUZIONE Il framework.NET. Un po di storia Sin dalla prima versione del sistema operativo Windows (1990 circa), nacque la necessità di far comunicare.
Code::Blocks Ambiente di sviluppo.
Code::Blocks Ambiente di sviluppo.
Costruttori e Distruttori
Corrado Cavalli Microsoft .NET MVP
I linguaggi di programmazione
Marco Barisione Estendere Python in C.
Type Checking (1° parte)
Differenze nei vari linguaggi di Elisa Trifirò e Barbara Tacchino
Generalità Linguaggio e Macchina Astratta
1 Strutture dati nel supporto a run time. 2 Entità presenti quando un programma va in esecuzione §programmi dutente (compilati) §routines del supporto.
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
DLL: Dynamic Linking Library
Concetti di base: header file, funzione main(),set caratteri C++, token, operatori, espressioni etc. Flusso di controllo, cicli, costrutti.
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Laboratorio di Linguaggi lezione VI: puntatori 2/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.
Laboratorio di Linguaggi lezione VIII Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea.
Laboratorio di Linguaggi lezione IV Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in.
Laboratorio di Linguaggi P R I M O C O M P I T I N O Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese.
Costruzione di Interfacce Lezione 12 C++STL
Introduzione al linguaggio C++ 5 lezioni
1 Corso di Informatica (Programmazione) Lezione 13 (21 novembre 2008) Programmazione in Java: stringhe e array.
Introduzione al linguaggio Java
Perché.Net e non più COM/DCOM ? Superamento dei problemi di COM: Richiede una infrastruttura "non semplice" da ogni applicazione (ad esempio Class Factory.
Corso di Informatica Applicata Lezione 6
Gestione dei Progetti Software 2 (a.a. 2004/05) - Lezione 3 1 JAVA e Internet: il World Wide Web Internet: milioni di computer collegati fra di loro attraverso.
CAPITOLO 4 LINGUAGGIO JAVA: COSTRUTTI DI BASE. ALFABETO Java adotta la codifica standard Unicode della società Unicode, Inc. (ftp://ftp.unicode.org) definito.
CAPITOLO 2 INTRODUZIONE AL LINGUAGGIO JAVA E ALL'AMBIENTE HOTJAVA.
nome: sequenza di caratteri usata per denotare un oggetto
memoria gestita staticamente:
Le classi Definizione di classe Attributi e metodi di una classe Costruttori e distruttori Private e public Funzioni friend Il puntatore this.
A.A. 2010/2011Ambienti di Programmazione per il Software di Base1 (Es. – 6) Ambienti di Programmazione per il Software di Base Le Stringhe in C Input.
Introduzione ad ASP.net
FUNZIONI... Una funzione permette di dare un nome a una espressione rendendola parametrica float f(){ return * sin(0.75); } float f1(int x) { return.
Corso di PHP.
C# LE BASI 2007 Prima lezione - Introduzione.
Per costruire unapplicazione occorre compilare il file (o i file se più duno) che contengono il testo del programma (file sorgente) Il risultato sono uno.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Introduzione a C#.
Ereditarietà e Polimorfismo
Java Contardi Carlo A.S. 2008/09.
1 Introduzione. 2 Le motivazioni In.net Framework iniziato nel 2000 rappresenta una svolta nella tecnologia Microsoft per andare oltre ai linguaggi esistenti.
Verso lo spazio profondo
Namespaces 1. Utilizzati per contenere tipi (classi, strutture, interfacce … ) ed altri namespaces La Class Library è organizzata gerarchicamente mediante.
I Metodi in Java Il termine "metodo" è sinonimo di "azione". Quindi, affinché un programma esegua qualche istruzione, deve contenere metodi.
15 maggio 2002 Avvisi: Ultima lezione: mercoledì 29 maggio II Esonero: mercoledì 5 giugno, ora da stabilire.
2000 Prentice Hall, Inc. All rights reserved. Capitolo 10 (Deitel) Strutture, unioni ed enumerazioni Sommario Introduzione Definire le strutture.
Laboratorio di Linguaggi lezione VII: variabili Globali e Locali Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali.
Sintassi base e struttura di un programma
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Array e stringhe Marco D. Santambrogio – Ver. aggiornata al 9 Agosto 2013.
Fopndamenti di programmazione. 2 La classe String Una stringa è una sequenza di caratteri La classe String è utilizzata per memorizzare caratteri La classe.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
JAVA Per iniziare. Verificare installazione javac –version java –version Cercare i files e sistemare eventualmente il path.
CORSO DI PROGRAMMAZIONE II Lezione 22
Programmazione in linguaggio C
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Array e “stringhe” Marco D. Santambrogio – Ver. aggiornata al 26 Marzo 2014.
1 Il linguaggio C Precisazioni sull’esperienza in laboratorio.
PiattaformePiattaformePiattaformePiattaforme Antonio Cisternino 11 Marzo 2005 OpenSourceOpenSourceOpenSourceOpenSource e ProprietarieProprietarieProprietarieProprietarie.
ALLOCAZIONE STATICA: LIMITI Per quanto sappiamo finora, in C le variabili sono sempre dichiarate staticamente –la loro esistenza deve essere prevista e.
Il linguaggio C Puntatori e dintorni.
Concetti Fondamentali sulla Programmazione
Copyright © Istituto Italiano Edizioni Atlas
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Array e “stringhe” Marco D. Santambrogio – Ver. aggiornata al 14 Marzo 204.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Array e “stringhe” Marco D. Santambrogio – Ver. aggiornata al 28 Ottobre 2014.
Introduzione alle Classi e agli Oggetti in Java 1.
Transcript della presentazione:

Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile: http://snipurl.com/f0cv http://mvp.support.microsoft.com

Agenda Perché usare C++ ... perché C++/CLI Carrellata sul linguaggio solo gli elementi del linguaggio utili per interop gestione della memoria managed/unmanaged pinning e marshalling mixed types C++ future directions

Perché usare C++ Rende semplice usare codice unmanaged Le definizioni PInvoke non sono sempre semplici da scrivere VC++ usa IJW (It Just Works) per usare codice nativo e codice managed allo stesso tempo Ad esempio si semplifica l'accesso alle librerie DirectX VC++ può creare dll/exe misti con codice C# / VB / C++ Rende semplice usare codice managed System.Xml semplifica la manipolazione di Xml System.Net semplifica l'accesso ai socket e al web System.Text.RegularExpressions semplifica le regex Idem per altre namespace/classi del framework

Perché un nuovo linguaggio? Perché C++/CLI? Le managed extensions erano complesse per aderire alle regole dello standard ISO (doppio underscore, etc.) cl /clr:oldSyntax continua a compilare le managed extensions un tool di Stan Lippman permette una migrazione quasi automatica C++/CLI è vicino alla standardizzazione ECMA (in questi giorni) ed ISO (probabilmente chiamata ISO C++09) C++/CLI ha una piacevole sintassi per lavorare sia con il mondo managed che unmanaged C++ Features Finalizzazione deterministica Template e generics Uso dei tipi nativi Multiple inheritance (unmanaged) STL, algoritmi generici Distinzione Puntatore/Puntato Copy construction, assignment CLR Features Garbage collector, finalizzatori Generics Reference e Value type Interfacce Verificabilità Security Proprietà, delegati, eventi

Novità in C++/CLI di cui non parleremo trivial properties: property String ^Name; indexed properties managed copy constructors delegate + event managed operator overloading boxing/unboxing safe_cast<> generics vs templates method overriding lock(...) jagged arrays STL.NET integrazione MFC / Winform integrazione Avalon compilazione parallela profile guided optimization OpenMP parallelism CLR Delay Loading

Veloce carrellata su C++/CLI Supporto distinto per tipi managed e unmanaged C++/CLI C# public ref class MyClass { ... } ; public ref struct MyClass { ... } ; MyClass ^c = gcnew MyClass(); public class MyClass { ... } MyClass c = new MyClass(); public value class MyValueType { ... } ; public value struct MyValueType { ... } ; MyValueType v; public struct MyValueType { ... } public interface class MyInterface { ... } ; public interface struct MyInterface { ... } ; public interface MyInterface { ... } public enum class MyEnum : char { ... } ; public enum struct MyEnum : char { ... } ; public enum MyEnum : char { ... } array<int> ^nums = {1,2,3} ; int[] nums = new int[] {1,2,3} Le specifiche si trovano qui: http://msdn.microsoft.com/visualc/homepageheadlines/ecma/default.aspx

I nuovi operatori ^ e % Introdotto nel linguaggio l' "handle" una sorta di puntatore managed ad un oggetto nel managed heap Il CLR tiene aggiornato il suo valore quando esegue la GC analogo del reference di C#, ma il reference in C++ esisteva già il simbolo è "hat" ^ su un handle si applicano gli operatori -> e * L'analogo di void* è Object^ Nuovo allocatore di memoria managed gcnew String ^s1 = gcnew String; String s2; continua ad essere un espressione valida Introdotto nel linguaggio il "tracking reference" Analogo del reference & di C++ classico, cioè un alias all'oggetto il simbolo è "%"

Distruzione deterministica C++/CLI introduce la distruzione deterministica delle risorse Non deve e non può riguardare la memoria, ma solo le risorse unmanaged. Questo è lo scopo del pattern Dispose. In pratica il Pattern Dispose viene implementato dal compilatore Implementazione completa di GC.SuppressFinalize Quando nella classe esiste il distruttore: In sostanza il distruttore della classe viene mappato su Dispose La classe implementa automaticamente IDisposable L'uscita dallo scope o una delete esplicita provoca la chiamata a Dispose (analogo dello statement using di C#, ma più semplice) Introdotto anche la sintassi per il finalizzatore La sintassi è analoga al distruttore  !NomeClasse() {...} Nel finalizzatore si mette la distruzione delle risorse Nella Dispose si mette la chiamata al finalizzatore

Istruire il precompilatore Il compilatore VC++ accetta di mixare codice managed e unmanaged anche nello stesso listato Alcune volte potrebbe esserci ambiguità su come compilare il codice Si può informare il compilatore con due #pragma #pragma managed #pragma unmanaged #pragma managed class Managed {...} ; #pragma unmanaged class Native {...} ; ...

Memoria: Interior Pointers Al contrario dell'handle, permette l'aritmetica dei puntatori Utile per la veloce manipolazione di array e buffer Trasparente: è usabile anche per tipi unmanaged (restituisce un puntatore classico) interior_ptr<type> name = &value; Esempio 1 array<int>^a = {1,2,3,4,5}; interior_ptr<int> ip = &a[0]; for(int i = 0; i<a->Length; i++) Console::WriteLine(++ip[i]); // output: 2, 3, 4, 5, 6 Esempio 2 String ^str1 = "Hello, world"; String ^str2 = str1; interior_ptr<String^> ip = &str1; *ip = "Ciao"; Console::WriteLine(str1 + " - " + str2); // output: Ciao – Hello, world

Memoria: Pinning Pointers pin_ptr<type> name = &value; void F(int* p); // Func unmanaged array<int>^ arr = …; pin_ptr<int> pi = &arr[0]; F(pi); // ptr unmanaged Interior Pointer interior_ptr<T> String ^str1 = "Hello, world"; // interior pointer al buffer della stringa (non è una copia) interior_ptr<const wchar_t> ip = PtrToStringChars(str1); // interior pointer senza 'const' interior_ptr<wchar_t> ip2 = const_cast<interior_ptr<wchar_t> >(ip); // pinning pointer  Il GC non può muovere il buffer pin_ptr<wchar_t> pp = ip2; // modifico il buffer for(int i=0; i<str1->Length; i++) ++pp[i]; // caratteri ascii incrementati Console::WriteLine(str1); // out Ifmmp-!xpsme Pinning Pointer pin_ptr<T> Unmanaged Pointer T*

Sguardo molto semplicistico in memoria Unmanaged heap memoria classica sempre ferma 30.00.00.00 sizeof(MyClass1) // pc è un "puntatore" MyClass1 *pc = new MyClass1(0x30); gg.hh.jj.kk MyClass1 &rc = *pc; // rc è un "reference"  alias gg.hh.jj.kk MyClass1 *pc2 = pc; Stack locale Managed heap GC muove i blocchi di memoria GC aggiorna i valori quando muove la memoria xx.yy.zz.tt 30.00.00.00 size unknown MyClass2 ^hc = gcnew MyClass2(); // hc è un handle. ^ si pronuncia hat pp.qq.rr.ss interior_ptr<MyClass2 ^> ip = &hc; // ip è un "interior pointer" pinned pin_ptr<MyClass2 ^> pp = &hc; pin_ptr<MyClass2 ^> pp2 = pp; ll.mm.nn.oo // pp e pp2 sono "pinning pointers" MyRefType %tr = *hc; // tr è un "tracking reference"

Marshalling di stringhe Stringhe Ansi Managed  Unmanaged Unmanaged  Managed Marshal::StringToHGlobalAnsi Marshal::PtrToStringAnsi Stringhe Unicode Managed  Unmanaged Unmanaged  Managed PtrToStringChars (#include <vcclr.h>) Marshal::PtrToStringUni Stringhe COM (BSTR) Managed  Unmanaged Unmanaged  Managed Marshal::StringToBSTR Marshal::PtrToStringBSTR

È tutto così semplice? ... quasi Fin ad ora abbiamo visto che: Creare immagini miste managed/unmanaged è semplice Eseguire il marshalling dei parametri è semplice Ci sono semplici strumenti per accedere alla memoria managed e unmanaged L'interoperabilità è possibile in due modi: P/Invoke esplicito (come in C#) IJW (=It Just Works) eseguendo il marshalling dei parametri E allora dov'è il problema?

Mixed types are not supported public ref class RefClass { public: POINT pt; // unmanaged struct }; public class Native { public: System::String ^str; }; error C4368: cannot define 'pt' as a member of managed 'ManagedClass': mixed types are not supported error C3265: cannot declare a managed 'str' in an unmanaged 'Native'

Tipi misti: tipi managed dentro tipi unmanaged GCHandle gcroot<> necessita #include<vcclr.h> non chiama automaticamente Dispose! msclr::auto_gcroot<> necessita #include <msclr\auto_gcroot.h> chiama automaticamente la IDisposable::Dispose se esiste #include <vcclr.h> using namespace System; public class Native1 { gcroot<String ^> str; }; #include <msclr\auto_gcroot.h> using namespace msclr; using namespace System; public class Native2 { auto_gcroot<String ^> str; };

Tipi misti: tipi unmanaged dentro tipi managed Brutta notizia: fin'ora nessun supporto ufficiale ma la soluzione è molto semplice .... In una classe managed si può avere un puntatore unmanaged ma è poi necessario gestire la sua distruzione (ciclo di vita) Molto meglio scrivere una classe con template che gestisce il ciclo di vita del puntatore Brandon Bray (uno degli ideatori della nuova sintassi) ne ha pubblicata una chiamata "Embedded" sul suo blog #include <windows.h> #include "Embedded.h" public ref class RefClass { Embedded<POINT> np; };

Cosa sono le calling convention? Una sorta di contratto alla compilazione che prevede: come passare gli argomenti delle funzioni ed il valore di ritorno quali registri della CPU devono essere salvati Le quattro convenzioni più usate oggi sono: __cdecl usato dalle librerie C e numerose API __stdcall conosciuta anche come "pascal", usata dalle Win32 API __fastcall usa i registri per passare gli argomenti __thiscall default per le chiamate a funzioni membro in C++

Cos'è il "double thunking"? Quando si compila codice con metadati ogni funzione ha due entry-point: uno con la calling-convention assegnata uno con la calling-convention CLR Quale viene usato? se il codice è compilato con /clr, l'entry-point di base è un thunk alla chiamata CLR se il codice è compilato senza /clr, l'entry point CLR è un thunk alla chiamata x86 Come viene scelto l'entry-point da usarsi? il compilatore è normalmente in grado di scegliere ma ... non può scegliere se la chiamata è un puntatore a funzione non può scegliere anche per le funzioni virtuali perché queste sono puntatori a funzioni

Cos'è il "double thunking"? Dove si presenta il problema? Le funzioni virtuali compilate in IL avranno sempre un thunk da unmanaged a managed. Questo è inevitabile. Se poi la chiamata viene fatta da codice managed, c'è un thunk supplementare: managed  unmanaged  managed Questo doppio passaggio si chiama "double thunking" Esiste una soluzione? La soluzione esiste solo se quella chiamata virtuale verrà solo chiamata dal mondo managed In questo caso è sufficiente marcare la funzione con la convenzione __clrcall forzando __clrcall si evita il double thunking virtual return-type __clrcall function-name(arguments);

Un assembly, mixed language Task complesso, nessun supporto di VS2005 Più semplice se si disabilitano i precompiled headers in tutti i progetti VC++ (ma è comunque usarli) La novità consiste nei .netmodule Il .netmodule è identico ad un assembly ma senza metadati per esempio non ha versione Il netmodule viene ri-compilato al link time Solo il linker di C++ ha questa capacità di ricompilazione a.cpp C++ Compiler a.obj EXE C++ Code D:\>cl /c /clr a.cpp C++ Linker C# Code D:\>csc /t:module c.cs c.cs C# Compiler c.netmodule

Un assembly, mixed language Esempio di una Winform C# che usa una business logic in C++/CLI Progetto 1: CppLogicClassLibrary Per semplicità precompiled headers disabilitati Si compila con VS.net EXE CppLogicClassLibrary CsFormClassLibrary CppStartWinform

Un assembly, mixed language Progetto 2: CsFormClassLibrary Eliminato Program.cs, l'entry point sarà in C++/CLI Si referenzia CppLogicClassLibrary e si usano le classi Si compila in VS.NET solo per il controllo sintattico Necessario compilare a mano  (ma si può lanciare make.bat come post-build action) Compilatore C# vogliamo un .netmodule dipendenza dal progetto C++/CLI csc /t:module /addmodule:..\CppLogicClassLibrary\debug\CppLogicClassLibrary.obj /resource:obj\Debug\CsFormClassLibrary.Form1.resources *.cs compilo tutti i sorgenti aggiungo le risorse (form)

Un assembly, mixed language Progetto 3: CppStartWinform Progetto C++/CLI Winform a cui si toglie la form Cambiare le opzioni da /clr:safe a /clr Aggiungere nel Linker – Input – Additional il .netmodule di C# e l'obj di C++ Aggiungere alla command line del linker l'opzione /LTCG Funge solo da entry point per l'applicazione managed Si può fare la build da VS.NET Risultato: 1 Assembly EXE con dentro tre immagini miste native/managed Ovviamente la dipendenza dal framework rimane

Qual'è il futuro di ISO C++? Ci sono problemi da risolvere per il cambio nell'evoluzione della crescita hardware niente più grossi aumenti di velocità nelle CPU aumento del numero di 'core' nelle CPU L'accesso diretto alla memoria impedisce una gestione efficiente nel determinare i problemi di concorrenza Work in progress su: gestione automatica della concorrenza ("concurs") gestione asincrona ("Futures") type inference lambda functions Linq

Domande?