2011-06-08 9 views
7

मैं सिस्टम का उपयोग कर int और double सरणी बनाने के लिए कुछ आईएल संस्थान लिख रहा हूं। रिफ्लेक्शन। नाम स्थान दें।डबल एरे के लिए आईएल जेनरेट करना

int सरणी बनाने के लिए मैं निम्नलिखित कोड का उपयोग कर रहा हूं।

LocalBuilder arr = gen.DeclareLocal(typeof(int)); 
gen.Emit(OpCodes.Ldc_I4_1); 
gen.Emit(OpCodes.Newarr, typeof(int)); 
gen.Emit(OpCodes.Stloc, arr); 
gen.Emit(OpCodes.Ldloc, arr); 
gen.Emit(OpCodes.Ldc_I4_0); 
gen.Emit(OpCodes.Ldc_I4, 500); 
gen.Emit(OpCodes.Stelem_I4); 

gen.Emit(OpCodes.Ldloc, arr); 
gen.Emit(OpCodes.Ldc_I4_0); 
gen.Emit(OpCodes.Ldelem_I4); 
gen.Emit(OpCodes.Call,typeof(Console).GetMethod("WriteLine",new Type[]{typeof(int)})); 

यह उम्मीद के अनुसार काम कर रहा है और कंसोल पर 500 प्रिंट करता है।

उसी तरह मैंने नीचे दिखाए गए double सरणी बनाने की कोशिश की।

LocalBuilder arr = gen.DeclareLocal(typeof(double)); 
gen.Emit(OpCodes.Ldc_I4_1); 
gen.Emit(OpCodes.Newarr, typeof(double)); 
gen.Emit(OpCodes.Stloc, arr); 
gen.Emit(OpCodes.Ldloc, arr); 
gen.Emit(OpCodes.Ldc_I4_0); 
gen.Emit(OpCodes.Ldc_R8, 500D); 
gen.Emit(OpCodes.Stelem_R8); 

gen.Emit(OpCodes.Ldloc, arr); 
gen.Emit(OpCodes.Ldc_I4_0); 
gen.Emit(OpCodes.Ldelem_I8); 
gen.Emit(OpCodes.Call,typeof(Console).GetMethod("WriteLine",new Type[]{typeof(double)})); 

दुर्भाग्य से यह काम नहीं करता है और जब मैं विधानसभा pereview उपयोग करते हुए उत्पन्न निरीक्षण यह त्रुटि निम्न मुझे दिया।

Microsoft (R) .NET Framework PE Verifier. Version 4.0.30319.1 
Copyright (c) Microsoft Corporation. All rights reserved. 

[IL]: Error: [C:\temp\Research\Research\bin\Debug\MyMod.exe : Foo::Main][offset 0x00000006][found ref array md 
array 'System.Double[]'][expected Double] Unexpected type on the stack. 
[IL]: Error: [C:\temp\Research\Research\bin\Debug\MyMod.exe : Foo::Main][offset 0x00000012] Expected single di 
mension array. 
2 Error(s) Verifying MyMod.exe 

इसके अलावा, मैं विधानसभा उत्पन्न निरीक्षण का उपयोग कर ildasm

.method privatescope static void Main$PST06000001() cil managed 
{ 
    .entrypoint 
    // Code size  28 (0x1c) 
    .maxstack 3 
    .locals init (float64 V_0) 
    IL_0000: ldc.i4.1 
    IL_0001: newarr  [mscorlib]System.Double 
    IL_0006: stloc.0 
    IL_0007: ldloc.0 
    IL_0008: ldc.i4.0 
    IL_0009: ldc.r8  500. 
    IL_0012: stelem.r8 
    IL_0013: ldloc.0 
    IL_0014: ldc.i4.0 
    IL_0015: ldelem.i8 
    IL_0016: call  void [mscorlib]System.Console::WriteLine(float64) 
    IL_001b: ret 
} // end of method Foo::Main 

आप किसी भी विचार है?

+0

सी # जेनरेट आईएल स्निपेट कैसा दिखता है? –

+2

मैं मानता हूं कि मैं आईएल में बहुत कमजोर हूं, लेकिन क्या आप घोषित प्रकार (int/double) के स्थानीय चर में सरणी संदर्भ संग्रहीत नहीं कर रहे हैं? क्या वह स्थानीय किसी प्रकार का संदर्भ नहीं होना चाहिए? –

+0

@Damien_The_Unbeliever: हाँ मैंने गलती की है और गलत तरीके से एक पूर्णांक चर में सरणी संदर्भ असाइन किया है। –

उत्तर

6
LocalBuilder arr = gen.DeclareLocal(typeof(int)); 
gen.Emit(OpCodes.Ldc_I4_1); 
gen.Emit(OpCodes.Newarr, typeof(int)); 
gen.Emit(OpCodes.Stloc, arr); 

के प्रकार int[] नहीं arr क्यों है?

मैं निश्चित रूप से दोनों संस्करणों के लिए शिकायत करता हूं।

तथ्य यह है कि यह पहले संस्करण के लिए चलता है बस 'किस्मत' * है।

* कारण अधिक जटिल है।

+0

धन्यवाद मैंने एक बड़ी गलती की है, परिवर्तनीय प्रकार डबल होना चाहिए [] मेरे कोड को बदलने के बाद लोकलबिल्डर एआर = जेन। डेक्लेयरलोकल (टाइपोफ (डबल [])); दुर्भाग्यवश int [] सरणी उदाहरण के लिए लोकलबिल्डर एआर = gen.DeclareLocal (टाइपऑफ (int)) के साथ काम करता है; –

+3

@Upul: कारण जटिल है कि यह क्यों काम करता है। सिस्टम 'int' को सूचक प्रकार के साथ संगत के रूप में देखता है। सी के समान आपको क्या करने की अनुमति देता है। – leppie

+0

मैं x86 पर हूं - मुझे लगता है कि यह x64 पर गिर जाएगा? (साथ ही, यह तकनीकी रूप से सूचक के बजाय संदर्भ नहीं है) –

संबंधित मुद्दे