Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP [email protected] MVP Profile: .

26
Mixed code: C++/CLI Mixed code: C++/CLI Raffaele Rialdi Raffaele Rialdi Visual Developer Security Visual Developer Security MVP MVP [email protected] [email protected] MVP Profile: http://snipurl.com/f0cv MVP Profile: http://snipurl.com/f0cv http:// http:// mvp.support.microsoft.com mvp.support.microsoft.com

Transcript of Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP [email protected] MVP Profile: .

Page 1: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Mixed code: C++/CLI Mixed code: C++/CLI

Raffaele RialdiRaffaele RialdiVisual Developer Security MVPVisual Developer Security [email protected]@vevy.comMVP Profile: http://snipurl.com/f0cvMVP Profile: http://snipurl.com/f0cv http://mvp.support.microsoft.comhttp://mvp.support.microsoft.com

Page 2: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

AgendaAgenda

• Perché usare C++ ... perché C++/CLIPerché usare C++ ... perché C++/CLI

• Carrellata sul linguaggioCarrellata sul linguaggio– solo gli elementi del linguaggio utili per interopsolo gli elementi del linguaggio utili per interop– gestione della memoria managed/unmanagedgestione della memoria managed/unmanaged– pinning e marshallingpinning e marshalling– mixed typesmixed types

• C++ future directionsC++ future directions

Page 3: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Perché usare C++Perché usare C++

• Rende semplice usare codice unmanagedRende semplice usare codice unmanaged– Le definizioni PInvoke non sono sempre semplici da scrivereLe definizioni PInvoke non sono sempre semplici da scrivere– VC++ usa IJW (It Just Works) per usare codice nativo e codice VC++ usa IJW (It Just Works) per usare codice nativo e codice

managed allo stesso tempomanaged allo stesso tempo– Ad esempio si semplifica l'accesso alle librerie DirectXAd esempio si semplifica l'accesso alle librerie DirectX– VC++ può creare dll/exe misti con codice C# / VB / C++VC++ può creare dll/exe misti con codice C# / VB / C++

• Rende semplice usare codice managedRende semplice usare codice managed– System.Xml semplifica la manipolazione di XmlSystem.Xml semplifica la manipolazione di Xml– System.Net semplifica l'accesso ai socket e al webSystem.Net semplifica l'accesso ai socket e al web– System.Text.RegularExpressions semplifica le regexSystem.Text.RegularExpressions semplifica le regex– Idem per altre namespace/classi del frameworkIdem per altre namespace/classi del framework

Page 4: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Perché un nuovo linguaggio? Perché un nuovo linguaggio? Perché C++/CLI?Perché C++/CLI?• Le managed extensions erano complesse per aderire alle Le managed extensions erano complesse per aderire alle

regole dello standard ISO (doppio underscore, etc.)regole dello standard ISO (doppio underscore, etc.)– cl /clr:oldSyntax continua a compilare le managed extensionscl /clr:oldSyntax continua a compilare le managed extensions– un tool di Stan Lippman permette una migrazione un tool di Stan Lippman permette una migrazione quasiquasi automatica automatica

• C++/CLI è vicino alla standardizzazione ECMA (in questi C++/CLI è vicino alla standardizzazione ECMA (in questi giorni) ed ISO (probabilmente chiamata ISO C++09)giorni) ed ISO (probabilmente chiamata ISO C++09)

• C++/CLI ha una piacevole sintassi per lavorare sia con il C++/CLI ha una piacevole sintassi per lavorare sia con il mondo managed che unmanagedmondo managed che unmanaged

C++ FeaturesC++ Features•Finalizzazione Finalizzazione deterministicadeterministica•Template Template ee generics generics•Uso dei tipi nativiUso dei tipi nativi•Multiple inheritance (unmanaged)Multiple inheritance (unmanaged)•STL, algoritmi genericiSTL, algoritmi generici•Distinzione Puntatore/PuntatoDistinzione Puntatore/Puntato•Copy construction, assignmentCopy construction, assignment

CLR FeaturesCLR Features•Garbage collector, finalizzatoriGarbage collector, finalizzatori•GenericsGenerics•Reference e Value typeReference e Value type•InterfacceInterfacce•VerificabilitàVerificabilità•SecuritySecurity•Proprietà, delegati, eventiProprietà, delegati, eventi

Page 5: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Novità in C++/CLINovità in C++/CLIdi cui di cui nonnon parleremo parleremo• trivial properties: property String ^Name;trivial properties: property String ^Name;• indexed propertiesindexed properties• managed copy constructorsmanaged copy constructors• delegate + eventdelegate + event• managed operator overloadingmanaged operator overloading• boxing/unboxingboxing/unboxing• safe_cast<>safe_cast<>• generics vs templatesgenerics vs templates• method overridingmethod overriding• lock(...)lock(...)• jagged arraysjagged arrays• STL.NETSTL.NET• integrazione MFC / Winformintegrazione MFC / Winform• integrazione Avalonintegrazione Avalon• compilazione parallelacompilazione parallela• profile guided optimizationprofile guided optimization• OpenMP parallelismOpenMP parallelism• CLR Delay LoadingCLR Delay Loading

Page 6: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Veloce carrellata su C++/CLIVeloce carrellata su C++/CLI

• Supporto distinto per tipi managed e unmanagedSupporto distinto per tipi managed e unmanaged

C++/CLIC++/CLI C#C#

public public ref classref class MyClass { ... } ; MyClass { ... } ;

public public ref structref struct MyClass { ... } ; MyClass { ... } ;

MyClass ^c = gcnew MyClass();MyClass ^c = gcnew MyClass();

public class MyClass { ... }public class MyClass { ... }

MyClass c = new MyClass();MyClass c = new MyClass();

public public value classvalue class MyValueType { ... } ; MyValueType { ... } ;

public public value structvalue struct MyValueType { ... } ; MyValueType { ... } ;

MyValueType v;MyValueType v;

public struct MyValueType { ... }public struct MyValueType { ... }

MyValueType v;MyValueType v;

public public interface classinterface class MyInterface { ... } ; MyInterface { ... } ;

public public interface structinterface struct MyInterface { ... } ; MyInterface { ... } ;

public interface MyInterface { ... }public interface MyInterface { ... }

public enum class MyEnum : char { ... } ;public enum class MyEnum : char { ... } ;

public enum struct MyEnum : char { ... } ;public enum struct MyEnum : char { ... } ;

public enum MyEnum : char { ... }public enum MyEnum : char { ... }

array<int> ^nums = {1,2,3} ;array<int> ^nums = {1,2,3} ; int[] nums = new int[] {1,2,3}int[] nums = new int[] {1,2,3}

Le specifiche si trovano qui:

http://msdn.microsoft.com/visualc/homepageheadlines/ecma/default.aspx

Page 7: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

I nuovi operatori ^ e %I nuovi operatori ^ e %

• Introdotto nel linguaggio l' "handle"Introdotto nel linguaggio l' "handle"– una sorta di puntatore managed ad un oggetto nel managed heapuna sorta di puntatore managed ad un oggetto nel managed heap– Il CLR tiene aggiornato il suo valore quando esegue la GCIl CLR tiene aggiornato il suo valore quando esegue la GC– analogo del reference di C#, ma il reference in C++ esisteva giàanalogo del reference di C#, ma il reference in C++ esisteva già– il simbolo è "hat" ^il simbolo è "hat" ^– su un handle si applicano gli operatori -> e *su un handle si applicano gli operatori -> e *– L'analogo di void* è Object^L'analogo di void* è Object^

• Nuovo allocatore di memoria managed Nuovo allocatore di memoria managed gcnewgcnew– String ^s1 = gcnew String;String ^s1 = gcnew String;– String s2; continua ad essere un espressione validaString s2; continua ad essere un espressione valida

• Introdotto nel linguaggio il "tracking reference"Introdotto nel linguaggio il "tracking reference"– Analogo del reference & di C++ classico, cioè un Analogo del reference & di C++ classico, cioè un aliasalias all'oggetto all'oggetto– il simbolo è "%"il simbolo è "%"

Page 8: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Distruzione deterministicaDistruzione deterministica

• C++/CLI introduce la distruzione deterministica delle risorseC++/CLI introduce la distruzione deterministica delle risorse– Non deve e non può riguardare la memoria, ma solo le risorse Non deve e non può riguardare la memoria, ma solo le risorse

unmanaged. Questo è lo scopo del pattern Dispose.unmanaged. Questo è lo scopo del pattern Dispose.– In pratica il Pattern Dispose viene implementato dal compilatoreIn pratica il Pattern Dispose viene implementato dal compilatore

• Implementazione completa di GC.SuppressFinalizeImplementazione completa di GC.SuppressFinalize

• Quando nella classe esiste il distruttore:Quando nella classe esiste il distruttore:– In sostanza il In sostanza il distruttoredistruttore della classe viene mappato su della classe viene mappato su DisposeDispose– La classe implementa automaticamente IDisposableLa classe implementa automaticamente IDisposable– L'uscita dallo scope o una delete esplicita provoca la chiamata a L'uscita dallo scope o una delete esplicita provoca la chiamata a

Dispose (Dispose (analogo dello statement usinganalogo dello statement using di C#, ma più semplice) di C#, ma più semplice)

• Introdotto anche la sintassi per il finalizzatoreIntrodotto anche la sintassi per il finalizzatore– La sintassi è analoga al distruttore La sintassi è analoga al distruttore !NomeClasse() {...} !NomeClasse() {...}– Nel finalizzatore si mette la distruzione delle risorseNel finalizzatore si mette la distruzione delle risorse– Nella Dispose si mette la chiamata al finalizzatoreNella Dispose si mette la chiamata al finalizzatore

Page 9: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Istruire il precompilatoreIstruire il precompilatore

• Il compilatore VC++ accetta di mixare codice managed e Il compilatore VC++ accetta di mixare codice managed e unmanaged anche nello stesso listatounmanaged anche nello stesso listato– Alcune volte potrebbe esserci ambiguità su come compilare il Alcune volte potrebbe esserci ambiguità su come compilare il

codicecodice

• Si può informare il compilatore con due #pragmaSi può informare il compilatore con due #pragma– #pragma managed#pragma managed– #pragma unmanaged#pragma unmanaged #pragma managed#pragma managed

class Managed {...} ;class Managed {...} ;

#pragma unmanaged#pragma unmanagedclass Native {...} ;class Native {...} ;

#pragma managed#pragma managed......

Page 10: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Memoria: Interior PointersMemoria: Interior Pointers

• Al contrario dell'handle, permette l'aritmetica dei puntatoriAl contrario dell'handle, permette l'aritmetica dei puntatori• Utile per la veloce manipolazione di array e bufferUtile per la veloce manipolazione di array e buffer• Trasparente: è usabile anche per tipi unmanaged Trasparente: è usabile anche per tipi unmanaged

(restituisce un puntatore classico)(restituisce un puntatore classico)

interior_ptr<interior_ptr<typetype> > namename = & = &valuevalue;;

Esempio 1Esempio 1

array<int>^a = {1,2,3,4,5};array<int>^a = {1,2,3,4,5};interior_ptr<int> ipinterior_ptr<int> ip = &a[0]; = &a[0];

for(int i = 0; i<a->Length; i++)for(int i = 0; i<a->Length; i++)Console::WriteLine(++ip[i]);Console::WriteLine(++ip[i]);

// output: 2, 3, 4, 5, 6// output: 2, 3, 4, 5, 6

Esempio 2Esempio 2

String ^str1 = "Hello, world";String ^str1 = "Hello, world";String ^str2 = str1;String ^str2 = str1;interior_ptr<String^> ipinterior_ptr<String^> ip = &str1; = &str1;*ip = "Ciao";*ip = "Ciao";Console::WriteLine(str1 + " - " + str2);Console::WriteLine(str1 + " - " + str2);

// output: Ciao – Hello, world// output: Ciao – Hello, world

Page 11: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Memoria: Pinning PointersMemoria: Pinning Pointers

Unmanaged PointerUnmanaged PointerT*T*

Pinning PointerPinning Pointerpin_ptr<T>pin_ptr<T>

Interior PointerInterior Pointerinterior_ptr<T>interior_ptr<T>

pin_ptr<pin_ptr<typetype> > namename = & = &valuevalue;; void F(int* p);void F(int* p); // Func unmanaged// Func unmanaged

array<int>^ arr = …;array<int>^ arr = …;pin_ptr<int>pin_ptr<int> pi = &arr[0]; pi = &arr[0];F(pi);F(pi); // ptr unmanaged// ptr unmanaged

String ^str1String ^str1 = "Hello, world"; = "Hello, world";

// interior pointer al buffer della stringa (non è una copia)// interior pointer al buffer della stringa (non è una copia)interior_ptr<const wchar_t> ip = PtrToStringChars(str1);interior_ptr<const wchar_t> ip = PtrToStringChars(str1);

// interior pointer senza 'const'// interior pointer senza 'const'interior_ptr<wchar_t> ip2 = const_cast<interior_ptr<wchar_t> >(ip);interior_ptr<wchar_t> ip2 = const_cast<interior_ptr<wchar_t> >(ip);

// pinning pointer // pinning pointer Il GC non può muovere il buffer Il GC non può muovere il bufferpin_ptr<wchar_t> pp = ip2;pin_ptr<wchar_t> pp = ip2;

// modifico il buffer// modifico il bufferfor(int i=0; i<str1->Length; i++)for(int i=0; i<str1->Length; i++)

++pp[i];++pp[i]; // caratteri ascii incrementati// caratteri ascii incrementatiConsole::WriteLine(Console::WriteLine(str1str1);); // out// out Ifmmp-!xpsme Ifmmp-!xpsme

Page 12: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Stack locale

Managed heap GCmuove i

blocchi di memoria

GCmuove i

blocchi di memoria

GCaggiorna i

valoriquando

muove la memoria

GCaggiorna i

valoriquando

muove la memoria

Sguardo molto semplicistico in Sguardo molto semplicistico in memoriamemoria

Unmanaged heap memoriaclassicasempreferma

memoriaclassicasempreferma

MyClass1 MyClass1 &rc&rc = *pc; = *pc;// rc è un "// rc è un "referencereference" " alias alias 30.00.00.0030.00.00.0030.00.00.0030.00.00.00 sizeof(MyClass1)

// pc è un "// pc è un "puntatorepuntatore""MyClass1 MyClass1 *pc*pc = new = new MyClass1(0x30);MyClass1(0x30);

gg.hh.jj.kkgg.hh.jj.kkgg.hh.jj.kkgg.hh.jj.kk

gg.hh.jj.kkgg.hh.jj.kkgg.hh.jj.kkgg.hh.jj.kkMyClass1 MyClass1 *pc2*pc2 = pc; = pc;

xx.yy.zz.ttxx.yy.zz.ttxx.yy.zz.ttxx.yy.zz.tt

30.00.00.0030.00.00.0030.00.00.0030.00.00.00 size unknown

MyClass2 MyClass2 ^hc^hc = gcnew = gcnew MyClass2();MyClass2();// hc è un // hc è un handlehandle. . ^̂ si pronuncia si pronuncia hathat

MyRefType MyRefType %tr%tr = *hc; = *hc;// tr è un "// tr è un "tracking referencetracking reference""

pinned

pin_ptrpin_ptr<MyClass2 ^> pp = &hc;<MyClass2 ^> pp = &hc;

pin_ptrpin_ptr<MyClass2 ^> pp2 = pp;<MyClass2 ^> pp2 = pp; ll.mm.nn.ooll.mm.nn.ooll.mm.nn.ooll.mm.nn.oo

// pp e pp2 sono "// pp e pp2 sono "pinning pointerspinning pointers""

pp.qq.rr.sspp.qq.rr.sspp.qq.rr.sspp.qq.rr.ssinterior_ptrinterior_ptr<MyClass2 ^> ip = &hc;<MyClass2 ^> ip = &hc;// ip è un "// ip è un "interior pointerinterior pointer""

Page 13: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Marshalling di stringheMarshalling di stringhe

Stringhe AnsiStringhe Ansi

Managed Managed Unmanaged Unmanaged Unmanaged Unmanaged Managed Managed

Marshal::StringToHGlobalAnsiMarshal::StringToHGlobalAnsi Marshal::PtrToStringAnsiMarshal::PtrToStringAnsi

Stringhe UnicodeStringhe Unicode

Managed Managed Unmanaged Unmanaged Unmanaged Unmanaged Managed Managed

PtrToStringCharsPtrToStringChars(#include <vcclr.h>)(#include <vcclr.h>)

Marshal::PtrToStringUniMarshal::PtrToStringUni

Stringhe COM (BSTR)Stringhe COM (BSTR)

Managed Managed Unmanaged Unmanaged Unmanaged Unmanaged Managed Managed

Marshal::StringToBSTRMarshal::StringToBSTR Marshal::PtrToStringBSTRMarshal::PtrToStringBSTR

Page 14: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

È tutto così semplice?È tutto così semplice?... quasi... quasi• Fin ad ora abbiamo visto che:Fin ad ora abbiamo visto che:

– Creare immagini miste managed/unmanaged è sempliceCreare immagini miste managed/unmanaged è semplice– Eseguire il marshalling dei parametri è sempliceEseguire il marshalling dei parametri è semplice– Ci sono semplici strumenti per accedere alla memoriaCi sono semplici strumenti per accedere alla memoria

managed e unmanagedmanaged e unmanaged– L'interoperabilità è possibile in due modi:L'interoperabilità è possibile in due modi:

• P/Invoke esplicito (come in C#)P/Invoke esplicito (come in C#)

• IJW (=It Just Works) eseguendo il marshalling dei parametriIJW (=It Just Works) eseguendo il marshalling dei parametri

• E allora dov'è il problema?E allora dov'è il problema?

Page 15: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Mixed types are not supportedMixed 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'

Page 16: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Tipi misti: tipi managed dentro Tipi misti: tipi managed dentro tipi unmanagedtipi unmanaged• GCHandleGCHandle• gcroot<>gcroot<>

– necessita #include<vcclr.h>necessita #include<vcclr.h>– non chiama automaticamente Dispose!non chiama automaticamente Dispose!

• msclr::auto_gcroot<>msclr::auto_gcroot<>– necessita #include <msclr\auto_gcroot.h>necessita #include <msclr\auto_gcroot.h>– chiama automaticamente la IDisposable::Dispose se esistechiama automaticamente la IDisposable::Dispose se esiste

#include <vcclr.h>using namespace System;

public class Native1{

gcroot<String ^> str;};

#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;};

#include <msclr\auto_gcroot.h>using namespace msclr;using namespace System;

public class Native2{

auto_gcroot<String ^> str;};

Page 17: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Tipi misti: tipi unmanaged Tipi misti: tipi unmanaged dentro tipi manageddentro tipi managed• Brutta notizia: fin'ora nessun supporto ufficiale ma la Brutta notizia: fin'ora nessun supporto ufficiale ma la

soluzione è molto semplice ....soluzione è molto semplice ....• In una classe managed si può avere un puntatore In una classe managed si può avere un puntatore

unmanagedunmanaged– ma è poi necessario gestire la sua distruzione (ciclo di vita)ma è poi necessario gestire la sua distruzione (ciclo di vita)

• Molto meglio scrivere una classe con template che gestisce Molto meglio scrivere una classe con template che gestisce il ciclo di vita del puntatoreil ciclo di vita del puntatore– Brandon Bray (uno degli ideatori della nuova sintassi) ne ha Brandon Bray (uno degli ideatori della nuova sintassi) ne ha

pubblicata una chiamata "Embedded" sul suo blogpubblicata una chiamata "Embedded" sul suo blog

#include <windows.h>#include "Embedded.h"

public ref class RefClass{

Embedded<POINT> np;};

#include <windows.h>#include "Embedded.h"

public ref class RefClass{

Embedded<POINT> np;};

Page 18: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Cosa sono le calling convention?Cosa sono le calling convention?

• Una sorta di contratto alla compilazione che prevede:Una sorta di contratto alla compilazione che prevede:– come passare gli argomenti delle funzionicome passare gli argomenti delle funzioni

ed il valore di ritornoed il valore di ritorno– quali registri della CPU devono essere salvatiquali registri della CPU devono essere salvati

• Le quattro convenzioni più usate oggi sono:Le quattro convenzioni più usate oggi sono:▪ __cdecl__cdecl usato dalle librerie C e numerose APIusato dalle librerie C e numerose API▪ __stdcall__stdcall conosciuta anche come "pascal",conosciuta anche come "pascal",

usata dalle Win32 APIusata dalle Win32 API▪ __fastcall__fastcall usa i registri per passare gli argomentiusa i registri per passare gli argomenti▪ __thiscall__thiscall default per le chiamate a funzioni membro in C++default per le chiamate a funzioni membro in C++

Page 19: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Cos'è il "double thunking"?Cos'è il "double thunking"?

• Quando si compila codice con metadati ogni funzione ha Quando si compila codice con metadati ogni funzione ha due entry-point:due entry-point:– uno con la calling-convention assegnatauno con la calling-convention assegnata– uno con la calling-convention CLRuno con la calling-convention CLR

• Quale viene usato?Quale viene usato?– se il codice è compilato con /clr, l'entry-point di base è un thunk alla se il codice è compilato con /clr, l'entry-point di base è un thunk alla

chiamata CLRchiamata CLR– se il codice è compilato senza /clr, l'entry point CLR è un thunk alla se il codice è compilato senza /clr, l'entry point CLR è un thunk alla

chiamata x86chiamata x86

• Come viene scelto l'entry-point da usarsi?Come viene scelto l'entry-point da usarsi?– il compilatore è normalmente in grado di scegliere ma ...il compilatore è normalmente in grado di scegliere ma ...– non può scegliere se la chiamata è un puntatore a funzionenon può scegliere se la chiamata è un puntatore a funzione– non può scegliere anche per le funzioni virtuali perché queste sono non può scegliere anche per le funzioni virtuali perché queste sono

puntatori a funzionipuntatori a funzioni

Page 20: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Cos'è il "double thunking"?Cos'è il "double thunking"?

• Dove si presenta il problema?Dove si presenta il problema?– Le funzioni virtuali compilate in IL avranno sempre un thunk da Le funzioni virtuali compilate in IL avranno sempre un thunk da

unmanaged a managed. Questo è inevitabile.unmanaged a managed. Questo è inevitabile.– Se poi la chiamata viene fatta da codice managed,Se poi la chiamata viene fatta da codice managed,

c'è un thunk supplementare:c'è un thunk supplementare:managed managed unmanaged unmanaged managed managedQuesto doppio passaggio si chiama "double thunking"Questo doppio passaggio si chiama "double thunking"

• Esiste una soluzione?Esiste una soluzione?– La soluzione esiste solo se quella chiamata virtuale verrà solo La soluzione esiste solo se quella chiamata virtuale verrà solo

chiamata dal mondo managedchiamata dal mondo managed– In questo caso è sufficiente marcare la funzione con laIn questo caso è sufficiente marcare la funzione con la

convenzione __clrcallconvenzione __clrcall– forzando __clrcall si evita il double thunkingforzando __clrcall si evita il double thunking

virtual virtual return-typereturn-type __clrcall__clrcall function-namefunction-name((argumentsarguments););

Page 21: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Un assembly, mixed Un assembly, mixed languagelanguage• Task complesso, nessun supporto di VS2005Task complesso, nessun supporto di VS2005• Più semplice se si disabilitano i precompiled headers in tutti i progetti Più semplice se si disabilitano i precompiled headers in tutti i progetti

VC++ (ma è comunque usarli)VC++ (ma è comunque usarli)• La novità consiste nei .netmoduleLa novità consiste nei .netmodule

– Il .netmodule è identico ad un assembly ma senza metadatiIl .netmodule è identico ad un assembly ma senza metadati

– per esempio non ha versioneper esempio non ha versione

• Il netmodule viene Il netmodule viene ri-compilatori-compilato al link time al link time• Solo il linker di C++ ha questa capacità di ricompilazioneSolo il linker di C++ ha questa capacità di ricompilazione

a.cppa.cpp

c.csc.cs

C++C++CompilerCompiler

D:\>cl /c /clr a.cppD:\>cl /c /clr a.cpp

D:\>csc /t:module c.csD:\>csc /t:module c.cs

EXEEXE C++ CodeC++ Code

C# CodeC# Code

a.obja.obj

c.netmodulc.netmodulee

C#C#CompilerCompiler

C++C++LinkerLinker

Page 22: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Un assembly, mixed Un assembly, mixed languagelanguage• Esempio di una Winform C# che usa una business logic in Esempio di una Winform C# che usa una business logic in

C++/CLIC++/CLI

– Progetto 1: CppLogicClassLibraryProgetto 1: CppLogicClassLibrary• Per semplicità precompiled headers disabilitatiPer semplicità precompiled headers disabilitati

• Si compila con VS.netSi compila con VS.net

EXEEXEEXEEXE

CppLogicClassLibrCppLogicClassLibraryary

CsFormClassLibraryCsFormClassLibrary

CppStartWinformCppStartWinform

Page 23: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Un assembly, mixed Un assembly, mixed languagelanguage• Progetto 2: CsFormClassLibraryProgetto 2: CsFormClassLibrary

– Eliminato Program.cs, l'entry point sarà in C++/CLIEliminato Program.cs, l'entry point sarà in C++/CLI– Si referenzia CppLogicClassLibrary e si usano le classiSi referenzia CppLogicClassLibrary e si usano le classi– Si compila in VS.NET solo per il controllo sintatticoSi compila in VS.NET solo per il controllo sintattico– Necessario compilare a mano Necessario compilare a mano (ma si può lanciare make.bat (ma si può lanciare make.bat

come post-build action)come post-build action)

csc /t:module /addmodule:..\CppLogicClassLibrary\debug\CppLogicClassLibrary.obj /resource:obj\Debug\CsFormClassLibrary.Form1.resources *.cs

csc /t:module /addmodule:..\CppLogicClassLibrary\debug\CppLogicClassLibrary.obj /resource:obj\Debug\CsFormClassLibrary.Form1.resources *.cs

vogliamo un vogliamo un .netmodule.netmodule

vogliamo un vogliamo un .netmodule.netmodule

dipendenza daldipendenza dalprogetto C++/CLIprogetto C++/CLI

dipendenza daldipendenza dalprogetto C++/CLIprogetto C++/CLI

aggiungoaggiungole risorse (form)le risorse (form)

aggiungoaggiungole risorse (form)le risorse (form)

compilo tutti icompilo tutti isorgentisorgenti

compilo tutti icompilo tutti isorgentisorgenti

Compilatore C#Compilatore C#Compilatore C#Compilatore C#

Page 24: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Un assembly, mixed Un assembly, mixed languagelanguage• Progetto 3: CppStartWinformProgetto 3: CppStartWinform

– Progetto C++/CLI Winform a cui si toglie la formProgetto C++/CLI Winform a cui si toglie la form– Cambiare le opzioni da /clr:safe a /clrCambiare le opzioni da /clr:safe a /clr– Aggiungere nel Linker – Input – Additional il .netmodule di C# e l'obj Aggiungere nel Linker – Input – Additional il .netmodule di C# e l'obj

di C++di C++– Aggiungere alla command line del linker l'opzione /LTCGAggiungere alla command line del linker l'opzione /LTCG– Funge solo da entry point per l'applicazione managedFunge solo da entry point per l'applicazione managed– Si può fare la build da VS.NETSi può fare la build da VS.NET

• Risultato: 1 Assembly EXE con dentro tre immagini miste Risultato: 1 Assembly EXE con dentro tre immagini miste native/managednative/managed– Ovviamente la dipendenza dal framework rimaneOvviamente la dipendenza dal framework rimane

Page 25: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Qual'è il futuro di Qual'è il futuro di ISOISO C++? C++?

• Ci sono problemi da risolvere per il cambio nell'evoluzione Ci sono problemi da risolvere per il cambio nell'evoluzione della crescita hardwaredella crescita hardware– niente più grossi aumenti di velocità nelle CPUniente più grossi aumenti di velocità nelle CPU– aumento del numero di 'core' nelle CPUaumento del numero di 'core' nelle CPU

• L'accesso diretto alla memoria impedisce una gestione L'accesso diretto alla memoria impedisce una gestione efficiente nel determinare i problemi di concorrenzaefficiente nel determinare i problemi di concorrenza

• Work in progress su:Work in progress su:– gestione automatica della concorrenza ("concurs")gestione automatica della concorrenza ("concurs")– gestione asincrona ("Futures")gestione asincrona ("Futures")– type inferencetype inference– lambda functionslambda functions– LinqLinq

Page 26: Mixed code: C++/CLI Raffaele Rialdi Visual Developer Security MVP malta@vevy.com MVP Profile:  .

Domande?Domande?