Excepții din Windows PowerShell, alte limbaje dinamice și cod C# executat dinamic atunci când un cod care vizează .NET Framework apelează unele metode

Se aplică la
Windows Vista Service Pack 2 Windows 7 Service Pack 1 Windows Server 2008 Service Pack 2 Windows Server 2008 R2 Service Pack 1 Windows 8 Windows Server 2012 Datacenter Windows Server 2012 Datacenter Windows Server 2012 Essentials Windows Server 2012 Foundation Windows Server 2012 Foundation Windows Server 2012 Standard Windows Server 2012 Standard Windows Server 2012 R2 Datacenter Windows Server 2012 R2 Essentials Windows Server 2012 R2 Foundation Windows Server 2012 R2 Standard Windows 8.1

Simptome

Atunci când codul care vizează Microsoft .NET Framework 4.5.1 sau Microsoft .NET Framework 4.5.2 și codul se leagă dinamic la metode (de exemplu, utilizând un script în Windows PowerShell, IronPython, IronRuby sau un alt limbaj dinamic), apelează metoda System.Runtime.InteropServices.Marshal.SizeOf sau System.Runtime.InteropServices.Marshal.PtrToStructure, este posibil să întâmpinați următoarele probleme.

Notă Codul care este deja compilat într-un executabil gestionat nu prezintă aceste probleme, cu excepția cazului în care acel cod utilizează cuvântul cheie dinamic în C#.

Problema 1

Apelurile la System.Runtime.InteropServices.Marshal.SizeOf aruncă următoarea excepție MethodInvocationException:

Notă

Tipul "<Nume> tip" nu poate fi reprezentate ca structură negestionată; nu se poate calcula o dimensiune semnificativă sau un decalaj.

Problema 2

Apelurile la System.Runtime.InteropServices.Marshal.PtrToStructure generează următoarea excepție MethodInvocationException:

Notă

Structura specificată trebuie să poată fi blitabilă sau să conțină informații despre aspect.

          

Problema 3

Apelurile la System.Runtime.InteropServices.Marshal.PtrToStructure generează următoarea excepție RuntimeBinderException:

Notă

Nu se poate efectua în mod implicit conversia tipului "void" în "object".

          

Cauză

Această problemă apare deoarece motoarele de scriptare și limbajele dinamice se pot lega la o nouă suprasarcină introdusă în .NET Framework. Mai exact, apelurile care utilizau anterior Marshal.SizeOf(Type) pot apela acum Marshal.SizeOf<T>(T), iar apelurile care utilizau Marshal.PtrToStructure(IntPtr, Type) pot apela acum Marshal.PtrToStructure<T>(IntPtr, T). Această modificare face ca metodele sau liantul runtime să genereze o excepție.

Soluție

Pentru a rezolva această problemă, modificați codul astfel încât să utilizeze supraîncărcarea corectă, dacă limba dvs. vă permite să faceți acest lucru. Dacă nu puteți specifica o anumită supraîncărcare a metodei, modificați codul astfel încât să utilizeze corect noua supraîncărcare a metodei.

Pentru invocarea dinamică C#

Adăugați o conversie la System.Type în cadrul apelului la metoda SizeOf sau metoda PtrToStructure. De exemplu:

object obj = System.Runtime.InteropServices.Marshal.PtrToStructure(ptr, (System.Type)type);
int size = System.Runtime.InteropServices.Marshal.SizeOf((System.Type)type);

Notă: Acest lucru este necesar doar când unul dintre argumentele metodei este dinamic.

Pentru scripturi Windows PowerShell

Adăugați o conversie la System.Type în cadrul apelului la metoda SizeOf sau metoda PtrToStructure. De exemplu:

$size = [System.Runtime.InteropServices.Marshal]::SizeOf([System.Type] $type)

$obj = [System.Runtime.InteropServices.Marshal]::PtrToStructure($ptr, [System.Type] $type)

Pentru scripturi IronPython

Creați o instanță de tip nou de acest tip, apoi utilizați supraîncărcarea metodei noi. De exemplu:

typeInstance = type()

size = System.Runtime.InteropServices.Marshal.SizeOf(typeInstance)

obj = System.Runtime.InteropServices.Marshal.PtrToStructure(ptr, typeInstance)

Stare

Microsoft a confirmat că aceasta este o problemă în produsele Microsoft care sunt listate în secțiunea „Se aplică la”.

Referințe