Вопросы с тегами [cil]

7

голосов
2

ответ
196

Просмотры

Может C # оператора генерировать ноны подключенного MSIL

Речь идет о C # спецификации языка и спецификации CIL языка, а также компании Microsoft и C # поведения компилятора Моно. Я строю некоторые инструменты анализа кода (независимо от того, что), которые работают на КСС. Учитывая несколько примеров коды, я заметил, что заявления коды (попытаться / поймать, IfElse, ifthen, петлю, ...) генерировать подключенные блоки MSIL. Но я хотел бы, чтобы убедиться, что я не могу писать C # код конструкции, которое дает Неподключённый MSIL. Более конкретно, я могу написать любое заявление, C #, который переводит с (что-то подобное): IL_0000: IL_0001: IL_0002: // дыра IL_001a: IL_001b: Я уже пробовал некоторые странные вещи, используя Гото и вложенные циклы, но, может быть, я не так сумасшедший, как некоторые пользователи будут.
Regis Portalez
1

голосов
1

ответ
52

Просмотры

Как оценить глобальные методы и поля при отладке?

При редактировании CIL, люди могут добавлять методы и поля, которые не принадлежат к какой-либо класса или пространства имен. В сборке есть внутренний класс класса, который содержит все эти глобал. Можно рассматривать эти методы кодов и полей с помощью IL инструментов (Mono.Cecil, dnlib) или декомпилировать инструменты (dnSpy). Есть ли способ, чтобы оценить или просмотреть значение в отладке в Visual Studio?
SGKoishi
1

голосов
2

ответ
1.1k

Просмотры

Итерация через параметры текущего метода

Эй, ребята мне нужно, чтобы иметь возможность обобщенно итерация через все аргументы текущей функции / Sub (для лесозаготовок), например, следующее: Public Sub SampleHandler (ByVal Sender как объект, ByVal е как EventArgs) Dim argholder в виде списка ( из Object) для каждого арг в getcurrentargs () '
Garandy
1

голосов
1

ответ
326

Просмотры

Parse CIL code with Regex

У меня есть * .il файл. Я хочу, чтобы найти все непустые методы в нем (.method). Например: .class частное авто beforefieldinit MyApp.Program ANSI расширяет [mscorlib] System.Object {// поймать его тело .method частной hidebysig статической силы основных (String [] арг) CIL удалось {.entrypoint // .maxstack 8 IL_0000: NOP IL_0001: RET} // поймать его тело .method общественного hidebysig specialname экземпляра rtspecialname недействительным .ctor () CIL удалось {// .maxstack 8 IL_0000: ldarg.0 IL_0001:. экземпляру вызова недействительным [mscorlib] System.Object :: т е р () IL_0006: RET} // не трогают, это пустая .method общественного hidebysig newslot строки виртуальный экземпляр Invoke (строка а) выполнения управляемой {} // ................ ...................... } Сейчас я' м делает это, используя строку класса. Это довольно нерационально. Я попытался с помощью Regex, но я не мог понять, как создать выражение регло поймать только методы (а не классы) только методы с непустыми телами Кто-нибудь может мне помочь?
Alan Coromano
1

голосов
1

ответ
97

Просмотры

Все возможные пути выхода из приложения .net?

Я просто добавил ряд (только MSIL) DLLs в мой проект и сделать вызовы методов в ней. Теперь приложение случайно падает, не оставляя ничего в журналах (стандартный вывод, STDERR, приложение журналы, которые должны регистрировать все исключения, окно и журналы приложений) в терминах сообщений об ошибках. Есть, конечно, несколько способов добраться до нижней части этого, как для Application.Exit оглавлению и т.д. в (декомпилированных) источников, но один вопрос, который является более общим, чем эта узкая проблема заключается в следующем: Какие есть пути для выхода из .net приложение с помощью MSIL, в дополнение к: Application.Exit Environment.Exit Environment.FailFast Process.GetCurrentProcess () Убей Вызов ничего через [DllImport] новый Thread (_ => {певд Exception ();}) Start (.. ) (спасибо user626528)
Eugene Beresovsky
1

голосов
2

ответ
141

Просмотры

Получить тип хранится в двоичном поле подписи

Предположим, у вас есть двоичное представление поля подписи в модуле .NET, как и 0604. 6-(FIELD) представляет собой поле соглашение о вызовах и 4 (ELEMENT_TYPE_I1) представляет собой примитивный тип I1 (см ECMA-335 для получения дополнительной информации КСС) , Подпись может быть из отладчика или сборки инспектора, это не важно. Что более важно, это возможно (с использованием методов, предоставляемых .NET), чтобы «разобрать» эту подпись и получить соответствующий тип .NET, что подпись, представляющая? Примеры: 0601 ⇒ System.Void 0604 ⇒ System.SByte 060E ⇒ System.String 061408020000 ⇒ System.Int32 [,]
IllidanS4
1

голосов
1

ответ
140

Просмотры

Почему методы C # 2 отдельных флагов: HasThis и IsStatic

Я играл с отражателем и РЕФЛЕКСИЛОМ, но когда я создал статический метод, он не работает. На некотором проведении проверки, я обнаружил, что методы имеют 2 различные параметры / флагов: IsStatic и HasThis. Что такое различию? Или же нет разницы и один из флагов просто не используется? Я посмотрел на методах расширения и конструкторы, однако методы расширения помечены как обычные статические методы, и конструктор, как обычные методы членов (в отношении этих 2 флагов).
kajacx
1

голосов
1

ответ
651

Просмотры

Заменить тело метода с органом другого метода с использованием Mono.Cecil?

С Mono.Cecil это выглядит довольно просто, когда мы можем просто установить Тело целевой MethodDefinition Тело источника MethodDefinition. Для простых методов, что хорошо работает. Но для некоторых методов, тогда пользовательского типа используется (например, для инициализации нового объекта), он не будет работать (за исключением брошенного во время записи сборки обратно). Вот мой код: // в текущем приложении общественный класс Form1 {общественность строки Test () {возвращении «Модифицированный тест»; }} // в другом узле общественного класса Target {публичной строка Test () {возвращение "Test"; }} // копирующий код, это работает для пары выше методов // контекст здесь, конечно, в текущем приложении вар targetAsm = AssemblyDefinition.ReadAssembly ( «target_path»); вар MR1 = targetAsm.MainModule.Import (TypeOf (Form1) .GetMethod ( "Тест")); вар TargetType = targetAsm.MainModule.Types.FirstOrDefault (е => e.Name == "Target"); вар м2 = targetType.Methods.FirstOrDefault (е => e.Name == "Тест"); вар m1 = mr1.Resolve (); вар m1IL = m1.Body.GetILProcessor (); Еогеасп (вар я в m1.Body.Instructions.ToList ()) {вар Ci = я; если (i.Operand является MethodReference) {вар MREF = i.Operand, как MethodReference; Ci = m1IL.Create (i.OpCode, targetType.Module.Import (MREF)); } Иначе, если (i.Operand является TypeReference) {вар TREF = i.Operand, как TypeReference; Ci = m1IL.Create (i.OpCode, targetType.Module.Import (TREF)); } Если {m1IL.Replace (я, CI) (CI = я!); }} // здесь источник тело должно его инструкция установить импортный штраф, // поэтому нам нужно просто установить его тело к цели тела m2.Body = m1.Body; // наконец, написать в другой выходной сборки targetAsm.Write ( «modified_target_path»); Приведенный выше код не ссылаться из любого места, я просто пробовал сам и узнал, что он работает для простых случаев (например, для испытания 2 методы, которые я написал выше). Но если метод источника (определенного в текущем приложении) содержит некоторый тип ссылки (например, какой-то конструктор инициализации ...), как это: общественный класс Form1 {общественная строка Test () {вар и = новый Uri ( «SomeUri») ; вернуться u.AbsolutePath; }} Тогда она не будет выполнена в момент написания сборки обратно. Исключение брошено является ArgumentException со следующим сообщением: «УЧАСТНИК System.Uri" объявлено в другом модуле и должно быть импортировано»На самом деле я встретил подобное сообщение и раньше, но это для вызовов методы, как (String.Concat). И это Поэтому я пытался импортировать MethodReference (вы можете увидеть, если внутри цикла Еогеаспа в коде я отправил). И действительно, что работал в этом случае. Но этот случай отличается, я не знаю, как импортировать используемые / ссылочных типов (в данном случае это System.Uri) правильно. Как я знаю, что должно быть использован результат импорта, для MethodReference вы можете увидеть, что результат используется для замены операнда для каждой инструкции. Но для типа ссылки в данном случае я совершенно не имею ни малейшего представления о том, как. для MethodReference вы можете увидеть, что результат используется для замены операнда для каждой инструкции. Но для типа ссылки в данном случае я совершенно не имею ни малейшего представления о том, как. для MethodReference вы можете увидеть, что результат используется для замены операнда для каждой инструкции. Но для типа ссылки в данном случае я совершенно не имею ни малейшего представления о том, как.
Hopeless
1

голосов
2

ответ
72

Просмотры

Является ли это CIL действительным?

Пусть 0 будет переменная типа объекта. Предположим, что это значение равно нулю. Пусть 1 переменная типа Boolean. Является КСС: ldloc 0 stloc 1 действует? Если это действительно, есть C #, который может составить до этого?
Nick
1

голосов
1

ответ
54

Просмотры

Анализ файлов .NET Module (.netmodule)

Как я могу анализировать модуль .NET? Я знаю, что могу открыть его в шестнадцатеричном читателя и работать оттуда, но это не совсем удобный способ идти о вещах. Есть ли ILDASM-подобный инструмент доступен?
BanksySan
1

голосов
1

ответ
71

Просмотры

.NET неявной типизации вызывает исключение RuntimeBinder

Я работаю с API называется ArcObjects и .NET 4.5. Я столкнулся ошибка «объект» не содержит определения для «AddValue» при использовании одного из объектов на API, но я думаю, что это может быть более общая проблема .NET, чем с этим API. Это ошибка, которая происходит во время выполнения. Для некоторого фона, ArcObjects все COM-объекты, поэтому библиотеки .NET просто обертки вокруг них. При работе с ArcObjects я, прежде всего, работа с Geodatabase, который является регулярным basicaly RDBS (с пространственным компонентом), где каждая строка называется функцией. Мой первый код попытка была следующим образом: // это IUniqueValueRenderer является ArcObject вар uvRenderer = новый ESRI.ArcGIS.Carto.UniqueValueRendererClass (), как IUniqueValueRenderer; // ... установить некоторые параметры на uvRenderer // ошибка происходит на этой линии. SampleAreaFeature. get_Value (idIndex) возвращает ненулевое целое 324 // SampleAreaFeature особенность в геоданных uvRenderer.AddValue (SampleAreaFeature.get_Value (1) .ToString (), "SampleField", redSymbol, как ISymbol); Определение AddValue является AddValue (строка, строка, ISymbol). Компилируется без ошибки или предупреждения и AddValue можно найти с помощью отражения во время выполнения. Я был в состоянии обойти эту проблему, изменив свою последнюю строку в следующем: значение строки = SampleAreaFeature.get_Value (idIndex) .ToString (); uvRenderer.AddValue (значение, "SampleField", redSymbol, как ISymbol); Даже незнакомец следующее не работает: значение вар = SampleAreaFeature.get_Value (idIndex) .ToString (); uvRenderer.AddValue (значение, "SampleField", redSymbol, как ISymbol); И это подводит меня к вопросу под рукой. Почему эти три фрагмента текста компиляции по-разному? Значение, которое явным образом не набрано производят различные результаты, оба из которых компилируется, но один из них не может связываться с методом AddValue во время выполнения. Вот IL, когда используется 'вар' ключевое слово: IL_00bb: вызов класса ESRI.ArcGIS.Geodatabase.IFeature DataReviewModule.ModGlobals :: get_SampleAreaFeature () IL_00c0: ldloc.2 IL_00c1: callvirt экземпляр объекта ESRI.ArcGIS.Geodatabase.IFeature :: get_Value (int32) IL_00c6: callvirt экземпляр 2 класса [mscorlib] System.Func`3 :: Invoke (0, 1!!) IL_00cb: stloc.3 IL_00cc: класс ldsfld [System.Core] System.Runtime.CompilerServices .CallSite`1 DataReviewModule.docWinReview / 'o__127' :: 'p__1' IL_00d1: brtrue.s IL_0125 IL_00d3: ldc.i4 256 IL_00d8: ldstr "AddValue" IL_00dd: ldnull IL_00de: ldtoken DataReviewModule.
danielm
1

голосов
1

ответ
85

Просмотры

Mono.Cecil производства «Invalid КСС»

Цель: Целью данного фрагмента является создание модифицированной версии, во время выполнения исполняемого, чтобы предотвратить его блокирование потока. Проблема: Я использую Mono.Cecil выполнить патч; Однако, кое-что о том, как это перекомпилированной вызывает ЛЮБУЮ модифицированный метод бросить InvalidProgramException. Чтобы доказать, что программа не является недействительной, я пошел вперед и переписал его с помощью модификации я хочу в C # и перекомпилировать его. Вручную компиляции программы с изменениями работали отлично; однако, IL из исправленных методов являются EXACT же для выравнивания файла, за исключением. Код:. Частный статическая сила PatchStartup (определение TypeDefinition) {ILProcessor иль = definition.Methods.First (х => x.Name == "Start") Body.GetILProcessor (); INT индекс = по умолчанию (INT); для (INT I = il.Body.Instructions. Count - 1; я = 0!; i--), если (il.Body.Instructions [I] .OpCode == OpCodes.Newobj) {индекс = I + 2; перерыв; } Список removedInstructions = новый список (); для (INT I = индекс; я <il.Body.Instructions.Count; я ++) removedInstructions.Add (il.Body.Instructions [I]); Еогеасп (вар я в removedInstructions) il.Remove (я); il.InsertAfter (il.Body.Instructions [il.Body.Instructions.Count - 1], il.Create (OpCodes.Ret)); il.Body.Variables.Clear (); il.Body.InitLocals = ложь; il.Body.Optimize (); il.Body.OptimizeMacros (); } Оригинал IL: // Токен: 0x06000029 RID: 41 RVA: Смещение 0x00002DE0 файла: 0x00000FE0 .method общественного hidebysig статической силы Start (строка [] арг) CIL удалось {// Размер заголовка:
ChubbyQuokka
1

голосов
1

ответ
31

Просмотры

Может ли LocalVarSig иметь атрибуты множественное ограничения?

На диаграмме синтаксиса LocalVarSig элементы CustomMod и Constraint находятся в цикле, таким образом, это означает, что может быть несколько элементов Constraint. При наличии более чем одного элемента Constraint, что его семантика? Спасибо!
tairqammar
1

голосов
1

ответ
0

Просмотры

Отношения между компиляции в x86 / x64 и MSIL

Так что я знаю, что если вы собираете для любого процессора, вы получите выход MSIL. Если вы собираете, как x86, вы получите выход x86. Мое понимание этого процесса, как в следующем коде .NET -> Compiler -> MSIL -> JIT скомпилированы в CLR -> Native Instruction Мой вопрос, если вы собираете в x86 / x64, значит ли это пропустить MSIL -> JIT компилируется в CLR шаг выше? Или это мое понимание прочь?
user2619824
1

голосов
3

ответ
0

Просмотры

CIL: “Operation could destabilize the runtime” exception

I've been playing with PostSharp a bit and I ran into a nasty problem. Following IL in Silverlight assembly: .method public hidebysig specialname newslot virtual final instance void set_AccountProfileModifiedAt(valuetype [mscorlib]System.DateTime 'value') cil managed { .maxstack 2 .locals ( [0] bool ~propertyHasChanged, [1] bool CS$4$0000) L_0000: nop L_0001: nop L_0002: ldarg.0 L_0003: call instance valuetype [mscorlib]System.DateTime Accounts.AccountOwner::get_AccountProfileModifiedAt() L_0008: ldarg.1 L_0009: call bool [mscorlib]System.DateTime::op_Inequality(valuetype [mscorlib]System.DateTime, valuetype [mscorlib]System.DateTime) L_000e: stloc.0 L_000f: ldarg.0 L_0010: ldarg.1 L_0011: stfld valuetype [mscorlib]System.DateTime Accounts.AccountOwner::accountProfileModifiedAt L_0016: br.s L_0018 L_0018: ldloc.0 L_0019: ldc.i4.0 L_001a: ceq L_001c: stloc.1 L_001d: ldloc.1 L_001e: brtrue.s L_002b L_0020: ldarg.0 L_0021: ldstr "AccountProfileModifiedAt" L_0026: call instance void Accounts.AccountOwner::NotifyPropertyChanged(string) L_002b: nop L_002c: leave.s L_002e L_002e: ret } triggers System.Security.VerificationException: Operation could destabilize the runtime. exception. Reflector parses it OK. What could be wrong with it? Update 1 Code is intended to work as follows: public void set_AccountProfileModifiedAt(DateTime value) { bool propertyHasChanged = this.AccountProfileModifiedAt != value; this.accountProfileModifiedAt = value; if (propertyHasChanged) { this.NotifyPropertyChanged("AccountProfileModifiedAt"); } } Update 2 I get specified exception inside the setter itself Update 3 Making non-static calls as callvirt (NotifyPropertyChanged) does not help Update 4 Commenting out (for test purposes) code: L_0018: ldloc.0 L_0019: ldc.i4.0 L_001a: ceq L_001c: stloc.1 L_001d: ldloc.1 and replacing L_001e: brtrue.s L_002b with L_001e: br.s L_002b does the trick but it's an unconditional return - not what I want. Update 5 If I use C# compiler to mimic required behavior (I still need to do that with Postsharp) I get following IL: .method public hidebysig specialname newslot virtual final instance void set_AccountProfileModifiedAt(valuetype [mscorlib]System.DateTime 'value') cil managed { .maxstack 2 .locals init ( [0] bool val, [1] bool CS$4$0000) L_0000: nop L_0001: ldarg.0 L_0002: call instance valuetype [mscorlib]System.DateTime Accounts.AccountOwner::get_AccountProfileModifiedAt() L_0007: ldarg.1 L_0008: call bool [mscorlib]System.DateTime::op_Inequality(valuetype [mscorlib]System.DateTime, valuetype [mscorlib]System.DateTime) L_000d: stloc.0 L_000e: ldarg.0 L_000f: ldarg.1 L_0010: stfld valuetype [mscorlib]System.DateTime Accounts.AccountOwner::accountProfileModifiedAt L_0015: ldloc.0 L_0016: ldc.i4.0 L_0017: ceq L_0019: stloc.1 L_001a: ldloc.1 L_001b: brtrue.s L_0029 L_001d: ldarg.0 L_001e: ldstr "AccountProfileModifiedAt" L_0023: call instance void Accounts.AccountOwner::NotifyPropertyChanged(string) L_0028: nop L_0029: ret } Note there are minor differences - extra br.s jump at L_0016 and some strange jump L_001e: brtrue.s L_002b. In compiler version I get direct jump to ret.
Nikolay R
1

голосов
2

ответ
0

Просмотры

Компиляция кода непосредственно в MSIL

Есть ли способ Скомпилируйте коду непосредственно в машинный код вместо MSIL, так что мы можем обойти JIT во время выполнения кода на компьютере. Если это возможно. Пожалуйста, дайте мне знать технику тоже. Спасибо
Raj Kumar
1

голосов
1

ответ
0

Просмотры

инструкция КСС «isinst »

Документация Инфраструктура ECMA Common Language говорит это о КСС «isinst класса» инструкции: Правильная CIL гарантирует, что класс является действительным TypeRef или ЬурейеЕ или typespec маркер, указывающий класс, и что OBJ всегда либо нулевой или ссылка на объект. Это означает, что ValueType не допускается, не так ли? Но mscorlib.dll содержит метод System.RuntimeTypeHandle :: Equals (объект OBJ) с помощью следующей инструкции: IL_0001: isinst System.RuntimeTypeHandle И System.RuntimeTypeHandle является ValueType. Кто-нибудь может поставить меня прямо здесь?
TonyK
1

голосов
2

ответ
0

Просмотры

Linking a precompiled MSIL file into an assembly?

Есть ли способ прекомпилировать файл MSIL и затем компоновщик ссылка .net, что в сборку .NET во время компиляции? Так, к примеру. У меня есть проект. Я скомпилировать его, декомпилировать его MSIL, и настроить MSIL. Итак, я хотел бы, чтобы скомпилировать и ссылку, что подправили MSIL файл в другой проект. Да, я + МОГ + перекомпилировать его в виде отдельного узла и просто ссылаться на него, но в данном конкретном случае, я не могу этого сделать. Содержание MSIL должно быть на самом деле в целевой сборке. Любые идеи, если это вообще возможно? До сих пор у меня не было никакой удачи найти что-нибудь. - EDIT-- Одно предложение ILMerge, которые могли бы работать. Я схватил последнюю копию сейчас и посмотрю, как это ярмарка. Единственная проблема у меня с этим состоит в том, что в прошлом, я нашел отладка будет трудно после слияния (или, по крайней мере, более трудным, чем если бы я не использовал ILMerge). Я надеялся, что, возможно, подправить файл PROJ включать скомпилированный MSIL непосредственно как часть процесса сборки, так что все будет по-прежнему легко отлаживается в среде IDE. - EDIT - Ну, не выглядит как ILMerge будет работать для этого сценария Во-первых, я получил это сообщение: исключение во время слияния: (TaskId: 32) ILMerge.Merge: Блок «Бла» не помечен как содержащий только управляемый код. (TaskId: 32) (Рассмотрите возможность использования / zeroPeKind вариант - но прочитайте документацию первой!) (TaskId: 32) в ILMerging.ILMerge.Merge () (TaskId: 32) в ILMerging.ILMerge.Main (String [] арг ) (TaskId: 32) Хорошо. Итак, что же, черт возьми, я добавляю / zeropekind и повторите попытку. Нет ошибок! Но в данном конкретном случае, DLL, которые объединены в несколько функций подправили в MSIL быть экспортированы как функции Cdecl. не в библиотеке DLL объединенной, они больше не экспортируются. Крысы. Возвращается на круги своя.
DarinH
1

голосов
1

ответ
0

Просмотры

ILDASM в папке x64

Я использую ildasm.exe (для просмотра сборок .NET) с места: C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin Но есть еще одна ildasm.exe в папке: C : \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ x64 есть ли разница между этими двумя ехе-х годов?
pnvn
1

голосов
2

ответ
482

Просмотры

Какие у меня есть варианты для создания .net байткод?

Я предпочел бы подход API вместо того, чтобы идти через КСС. Существуют ли какие-либо высокие рамки уровня я мог бы использовать, или я должен использовать Reflection.Emit? ОБНОВЛЕНИЕ В исследовании далее я заметил, что есть (потенциально) противоречивые объяснения по поводу того, что используется в задней части # компилятор Mono mcs.exe C. Некоторые говорят, что «Mono C # компилятор генерирует ECMA CIL изображения с помощью использования System.Reflection.Emit API», а в другом месте он заявил, что по состоянию на сентябрь 2011 MCS использует реализацию ikvm.net для генерации байт-коды.
Andrew Matthews
1

голосов
1

ответ
375

Просмотры

VerificationException при попытке запустить DynamicMethod с Action.Method агд

Я стараюсь, чтобы действие обстреляли, когда событие происходит, игнорируя параметры событий (по крайней мере сейчас). Я нахожу, что это событие с помощью отражения, а затем создать динамический метод сопоставления ожидаемой подписи (нет никакой гарантии, что только Отправитель / EventArgs) и оттуда попытаться вызвать действие. /// /// Выполнить действие, когда срабатывает событие, игнорируя его параметры. /// 'тип' аргумент element.GetType () /// BOOL TryAsEvent (тип Type, UIElement элемент, строка actionStr, действие акта) {попробуйте {// Получить события Информация о вар EventInfo = type.GetEvent (actionStr); // Что-то вроде «Клик» вар типСобытия = eventInfo.EventHandlerType; // Получаем параметры вар MethodInfo = eventType.GetMethod ( "Вызов"); вар parameterInfos = methodInfo.GetParameters (); . Вар paramTypes = parameterInfos.Select ((информация => info.ParameterType)) ToArray (); // Создать метод уаг DynamicMethod = новый DynamicMethod ( "", TYPEOF (пустоту), paramTypes); // Статический метод, который будет вызывать действие (от нашего параметра «акта») // Необходимо, потому что само действие не было признано в качестве статического метода // вызвавшего Exec InvalidProgramException MethodInfo = TypeOf (ThisClass) .GetMethod ( "ExecuteEvent «); // Генерирует IL уаг иль = dynamicMethod.GetILGenerator (); il.DeclareLocal (TypeOf (MethodInfo)); // MethodInfo miExecuteAction = act.Method; // закомментирована некоторые испытания и неудачи вещи il.Emit (OpCodes.Ldobj, act.Method); //il.Emit(OpCodes.Stloc, ЖХ); //il.Emit(OpCodes.Ldloc, ЖХ); //il.Emit(OpCodes.Ldobj, act.Method); //il.Emit(OpCodes.Ldarg_0); //il.Emit(OpCodes.Pop); il.EmitCall (OpCodes.Call, EXEC, NULL); il.Emit (OpCodes.Ret); // Тест метод (событие при испытании имеет обработчик принимая 2 арг): // вар act2 = dynamicMethod.CreateDelegate (типСобытия); //act2.DynamicInvoke(new объекта [] {NULL, NULL}); // Добавляем обработчик обработчик вар = dynamicMethod.CreateDelegate (типСобытия); eventInfo.AddEventHandler (элемент, обработчик); возвращает истину; } {Улов вернуться ложным; }} Государственной статической силы ExecuteEvent (MethodInfo я) {i.Invoke (NULL, NULL); } Может кто-нибудь сказать мне, как достичь этого? UPDATE: Вот краткий файл VS11 проект имитируя реальный сценарий: Загрузить обновление (FIX): общественный класс Program {государственной статической силы Main (string [] арг) {вар х = новый Provider (); Новая программа () TryAsEvent (x.GetType (), х, "Клик", новая программа () TestInstanceMethod.). // Используйте эту лямбду вместо того, чтобы проверить статическое действие // () => Console.WriteLine ( «сожжено действие, когда событие было.»)); x.Fire (); Console.ReadLine (); } Общественного недействительный TestInstanceMethod () {Console.WriteLine ( "сожжены действия, когда событие было."); } /// /// Выполнить действие, когда срабатывает событие, игнорируя его параметры. /// BOOL TryAsEvent (тип Тип, объект элемент, строка actionStr, действие акта) {попробуйте {вар getMFromH = TypeOf (MethodBase) .GetMethod (» // Создать метод уаг DynamicMethod = новый DynamicMethod ( "", TYPEOF (пустоту), paramTypes); // Статический метод, который будет вызывать действие (от «акта» нашего параметра) вар процесс = TypeOf (Программа) .GetMethod (! Предназначаться = NULL // Вызвать соответствующий метод на основе объема действия «ExecuteEvent»: «ExecuteEventStati») ; // Генерирует IL уаг иль = dynamicMethod.GetILGenerator (); если (цель! = NULL) // Поместить экземпляр объекта на стеке при работе с нестатическим действиями il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldtoken, act.Method); il.Emit (OpCodes.Call, getMFromH); il.Emit (OpCodes.Call, Exec); il.Emit (OpCodes.Ret); // Добавляет обработчик уаг обработчик = цель! = NULL // Вызова с целью OBJ, если мы работаем с нестатическим действием? dynamicMethod.CreateDelegate (типСобытия, цель): dynamicMethod.CreateDelegate (типСобытия); eventInfo.AddEventHandler (элемент, обработчик); возвращает истину; } Задвижка (Исключение ех) {Console.WriteLine ( "Исключение:" + ех); вернуться ложным; }} государственной статической силы ExecuteEventStati (MethodInfo я) {i.Invoke (NULL, NULL); } Государственной статической силы ExecuteEvent (объект о, MethodInfo я) {i.Invoke (о, NULL); }} А вот несвязанный код этого примера (в случае, если кто-то хочет скопировать и вставить): общественный класс Provider {публичное мероприятие MyRoutedEventHandler Нажмите; общественного недействительными Огонь () {если (Нажмите! = NULL) Нажмите (это, новые MyRoutedEventArgs ()); }} Открытый делегат пустот MyRoutedEventHandler (объект отправителя, MyRoutedEventArgs е); MyRoutedEventArgs общественного класса: RoutedEventArgs {общественных MyRoutedEventArgs () {} общественных MyRoutedEventArgs (RoutedEvent RoutedEvent): это (RoutedEvent, (объект) NULL) {} общественных MyRoutedEventArgs (RoutedEvent RoutedEvent, источник объекта): основание (RoutedEvent, источник) {}}
natli
1

голосов
1

ответ
84

Просмотры

Создание больших файлов в .NET

Я хотел бы спросить о двух вещах, о .NET исполняемых файлов: .NET исполняемый файл в формате PE. Означает ли это, что адрес, генерируемый компилятором CIL от начала файла (адрес + size_of_headers)? Или эти адреса используются только при выполнении изображения в памяти? Можно ли генерировать (на CIL компилятор) исполняемый с размером больше 4 Гб? Если да, то что делает компилятор делать, если он должен вызвать метод с конца файла или ответвлением байт выше предела 4GB? Это правда, я никогда не видел ни C # исполняемый файл больше 4 Гб, я просто любопытными.
user35443
1

голосов
1

ответ
136

Просмотры

Глядя FieldRef и FieldDef лексемы метаданных с помощью отражения

Я работаю над программой, которая предварительно компилирует байт-код из сборок .NET. Эта программа сама программа .NET - до сих пор я был в состоянии использовать отражение, чтобы извлечь всю необходимую информацию, включая сам байткод. Тем не менее, я столкнулся с проблемой, реализующего перевод ldfld. ldfld и подобные инструкции имеют метаданные маркера в пределах их кодирования, который ссылается на FieldRef или FieldDef. Я понимаю, это элементы в таблицах метаданных, внедренных в файл PE Ассамблеи. В худшем случае, у меня есть достаточно информации из ECMA-335, чтобы открыть файл PE и посмотреть все это на себя, но это очень много работы и не согласуется с другой информацией, которая я получаю через Reflection, поэтому я предпочел бы чтобы сделать этот поиск с помощью отражения. Тем не менее, я не могу найти какие-либо методы System.Reflection. Ассамблея, что искать маркер метаданных. (Я, возможно, просто пропустили его.) Я не могу сделать поиск на что-либо более конкретного, чем сборки, потому что я знаю только сборку реферирования, пока я не вижу метаданные (поймать-22.) На самом деле, как было отмечено в комментариях, Я даже не знаю, что сборка в поле не определено в, до изучения метаданных. Есть ли способ, чтобы найти такие маркеры метаданных с помощью отражения?
Kevin
1

голосов
1

ответ
478

Просмотры

Портативная поддержка многопоточности в байт-коды / промежуточные языки / бэкэндов компилятора?

Я работал на синтаксический анализатор для языка программирования, который требует поддержки многопоточности. При изучении того, что должно быть бэкенд моего компилятора, я заметил, что я не могу найти много информации о многопоточности для таких вещей, как КСС, LLVM IR, GCC RTL, или JVM байт-кода. Я не могу найти некоторые ссылки о том, как сделать такой код поточно, но ничего о том, как, скажем, создавать или вилочные нити. Я сигналов использования конечно или что-то, чтобы напрямую взаимодействовать с операционной системой, но это непереносимо и подвержен ошибкам. Действительно ли это так, что там просто нет переносимого способа для управления потоками на этих языках низкого уровня? Должен ли я составить до высокого (вдовцов) -уровня языка как C вместо этого?
jpt
1

голосов
1

ответ
52

Просмотры

peverify ClassLayout имеет родитель TYPEDEF отмеченной AutoLayout

После преобразования моего компилятора использовать Mono.Cecil вместо Reflection.Emit, я получаю сообщение об ошибке от peverify. Microsoft (R) .NET Framework PE Verifier. Версия 4.0.30319.33440 Copyright (с) Корпорация Microsoft. Все права защищены. [MD]: Ошибка: ClassLayout имеет родителя TYPEDEF маркер = 0x02000002 маркированные AutoLayout. [Лексема: 0x00000001] 1 ошибка (ы) Проверка test.exe Я не смог найти какую-либо информацию о том, что это значит. Я могу предоставить исполняемый файл, если это необходимо.
MI3Guy
1

голосов
3

ответ
198

Просмотры

How can I obtain execution trace of a C# application at statement level?

Это моя проблема. У меня есть exe-файл, написанный на C #. У меня нет доступа к исходному исходному коду или PDB файлу. Я хочу, чтобы получить след того, что выполняется внутри метода на уровне оператора. Я знаю, что C # источник преобразуется в CIL и далее компилируется во время выполнения. Я нашел .NET профайлер, которые предлагают трассировки выполнения, состоящие из методов, возвращаемые значений и значений параметров. Некоторые инструменты, которые я нашел являются: dotTrace, RedGate МУРАВЬЕВ, Telerik justTrace, время выполнения потока. Я хотел бы получить след CIL команды эквивалентны для каждого оператора. Я знаю, что там может быть дальнейшие оптимизации компилятора, которые могут модифицировать код CIL или другой тип компиляции управляемого кода (краткая информация). Один из подходов для автоматического добавления рубок PostSharp но снова предлагает слишком высокоуровневые для моего случая. Насколько я понимаю, CLRProfiler предлагает методы API для ввода метода и точек выхода и так далее. Там нет API, чтобы проследить выполненные заявления. Идея, что у меня до сих пор вручную написать код инжектора на уровне CIL, как описано здесь (часть-1 и частично 2), который для каждого оператора будет печатать эквивалентный код CIL. Кто-нибудь лучшее представление о том или о каком-либо подобном инструменте? Для бинарных сборок, Intel Pin может обеспечить аналогичные функциональные возможности. Обновление Я не хочу, чтобы просто читать исходный код, я хочу посмотреть, что выполняется. Я хорошо знаю всех декомпиляции. Я делаю это в контексте запутывания и деобфускации. Например, если у меня есть метод, который вычисляет количество fibonnacci и на том, что он применяется запутывание управления потоком и другие методы запутывания, просто читая исходный код не достаточно. Я хочу посмотреть, как выполняется этот метод. Мне нужно динамическое отслеживание.
cipri.l
1

голосов
1

ответ
54

Просмотры

Происходит ли границы проверка логики в MSIL или машинном коде

Я только начал плескаться в удивительном мире MSIL, но я не могу найти какие-либо ответы здесь о том, где происходит граница проверка. вставить ли C # компилятор инструкции MSIL, которые выполняют ограничивающей проверки, или же JIT компилятор MSIL вставить их для всех применимых инструкций MSIL при переводе тех машинный код? Я спрашиваю потому, что мне нужно знать, нужно ли я добавить эти инструкции, когда я произвожу функции с помощью MSIL напрямую. EDIT: После приема одного ответа и пытается проверить, оказывается неверным. Следующий код фактически не удается. Шагая через отладчик показывает, что второй тест пишет за пределы массива, а третий тест делает гораздо хуже: статический класс ArrayExtensions {#if ложной государственной статической силы ClearRangeReferenceImplementation (байт [] буфера, внутр смещение, INT ByteCount) {для (INT = ток смещения, ток <офсет + ByteCount; ++ ток) {буфер [ток] = 0; }} #Endif частных статических действий MemclearRaw только для чтения = InitMemclearRaw (); частный статические действия InitMemclearRaw () {DynamicMethod memclearMethod = новый DynamicMethod ( "Memclear", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, пустое, новый тип [] {TypeOf (IntPtr), TypeOf (INT), TypeOf (целое) }, TypeOf (это), правда); ILGenerator IL = memclearMethod.GetILGenerator (); il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldarg_1); il.Emit (OpCodes.Add); il.Emit (OpCodes.Ldc_I4_0); il.Emit (OpCodes.Ldarg_2); il.Emit (OpCodes.Initblk); il.Emit (OpCodes.Ret); вернуться (Действие) memclearMethod. CreateDelegate (TypeOf (Action)); } /// /// Удаляет указанный диапазон указанного буфера в наиболее оптимальным образом доступен, не прибегая к PInvoke или инлайн сборки. /// /// Буфер для действию. /// Смещение в буфере, где очистка должна начаться. /// Число байтов, которые будут очищены. государственный статическая сила ClearRange (этот байт [] буфер, Int смещения, счетчик целого) {если (кол == 0) возвращение; GCHandle ручка = GCHandle.Alloc (буфер, GCHandleType.Pinned); попробовать {MemclearRaw (handle.AddrOfPinnedObject (), смещение, счет); } Наконец {handle.Free (); }}} [TestClass] общественный класс TestArrayExtensions {/// /// Выполняет тесты на провал. /// [TestMethod] общественные пустоты Array_ClearRangeExceptions () {байт [] B = Rand.NewBytes (0, 100); AssertExceptionClearRange (нуль, 0, b.Length, TypeOf (NullReferenceException)); б = Rand.NewBytes (0, 100); AssertExceptionClearRange (б, 0, b.Length + 1, TypeOf (ArgumentOutOfRangeException)); б = Rand.NewBytes (0, 100); AssertExceptionClearRange (б, 0, -1, TypeOf (ArgumentOutOfRangeException)); б = Rand.NewBytes (0, 100); AssertExceptionClearRange (б, -1, b.Length, TypeOf (ArgumentOutOfRangeException)); } Частных статических пустот AssertExceptionClearRange (байт [] буфера, Int смещение, счетчик INT, тип ExceptionType) {{ArrayExtensions.ClearRange попробовать (буфер, смещение, счет); Assert.Fail ( "ArrayExtensions.
James
1

голосов
1

ответ
126

Просмотры

Бесконечный цикл при использовании RemoteTestRunner с оптимизированной единицей кодом теста

Некоторые контексты первым: Я работаю на инструмент тестирования мутации для C # + NUnit, и ради скорости я использую внутренний класс NUnit 2.6.4 сборки сердечника (RemoteTestRunner) для выполнения тестов (см метод DoTests в дно) в отдельном AppDomain. Проблема: У меня есть модульный тест, который опрашивает переменную, пока она не станет не пустой. Эти переменный является словарь назначить в качестве нуля, а затем передать в реальный словарь посредством действий, вызванных таймером. При построении тестовой сборки с оптимизацией коды, это никогда не закончится. Проблематично код: [Тест] общественный недействительный WeirdOne () {использование (вар аккумуляторного = Новый аккумулятор (5, TimeSpan.FromMilliseconds (500))) {словарь упаковка = NULL; accumulator.NewPack + = р => пакет = р; accumulator.Add ( "D"); accumulator.Add ( "А"); аккумулятор. Добавить ( "M"); accumulator.Add ( "N"); в то время как (пакет == NULL); Assert.That (pack.Count, Is.EqualTo (4)); }} Здесь суть с implem заряда, если необходимо. То, что я нашел: Если я ставлю что-то внутри время цикла (протестировано с Thread.Sleep и WriteLine), то у меня нет больше проблем работает тест до конца Если я вызвать NewPack Action от метода Accumulator.Add, тест идет до конца Просто чтобы убедиться, что таймер эффективно выполнять свою работу, я пытался добавить File.Create () как раз перед вызовом NewPack действий. Файл был создан с или без оптимизации кода Нет проблем при запуске с NUnit-консоль (2.6.2 / 2.6.4), с или без оптимизации Поскольку NUnit может запустить это и идти до конца, я подозреваю, что я пропускаю что-то, когда инстанцирование всех RemoteTestRunnner» s окружающая среда. кто сталкиваются ли этот вид отладки / выпуска проблемы сборки? Любой свинец о том, что я не хватает? Спасибо за прочтение ! Изменить: Как отметил Алексей Л. определить эту переменную в качестве поля экземпляра и пометить его как летучие избежать бесконечного цикла, но до сих пор ни намека о том, как NUnit-консольной работы, что из
shorty_ponton
1

голосов
1

ответ
204

Просмотры

Как получить TYPEDEF от TypeSpec

Я пытаюсь реализовать управляемый отладчик, глядя на образец MDBG. В настоящее время я застрял пытается получить базовые методы иерархии классов с использованием IMetaDataImport. EnumMethods, что я использую, перебирает MethodDef маркеры, представляющие методы указанного типа. Но я хочу, чтобы перечислить все методы в иерархии классов. Для этого я использую GetTypeDefProps, который возвращает ptkExtends, что маркер, представляющий базовый класс. Проблема заключается в том, что базовый класс может быть представлен TYPEDEF, TypeRef или TypeSpec. Как я могу получить базовый класс TYPEDEF от относительной TypeSpec? Я прочитал спецификации ECMA часть II, но это не помогло мне много ... Вот то, что я до сих пор: INT размер; TypeAttributes pdwTypeDefFlags; m_importer.GetTypeDefProps (m_typeToken, нуль, 0, из размера, из pdwTypeDefFlags, из ptkExtends); // ptkExtends правильно TypeSpec маркер IntPtr ppvSig; UINT pcbSig; m_importer.GetTypeSpecFromToken (ptkExtends, из ppvSig, из pcbSig); // Я получаю подпись TypeSpec Blob в ppvSig, как использовать его, чтобы получить TYPEDEF ?!
3615
1

голосов
1

ответ
80

Просмотры

сборка MSIL: Неожиданное OutOfMemoryException в конструкторе класса

Я пишу компилятор, который выводит сборку .NET (с использованием Mono.Cecil, хотя я не верю, что Cecil имеет отношение к этой проблеме). Одной из особенностей компилятора требует, чтобы класс будет иметь сгенерированный компилятором вложенный класс с некоторыми методами поддержки; внешний класс имеет статическое поле, так что каждый класс имеет эффективно одноэлементный ссылающийся объект вложенного класса. Для инициализации этого, любой такой класс имеет конструктор класса для создания экземпляра вложенного класса и хранить его в поле. Проблема: Когда мой внешний класс универсальный класса, я сделать вложенный класс родовым тоже (так как он должен создавать объекты внешнего класса). Сформированный IL проходит через peverify штраф, и выглядит хорошо, на мой взгляд, но класс конструктор, создающий экземпляр вложенного класса бросает OutOfMemoryException во время выполнения. Я' Ве разобрал узел с ILDASM, похудел его до минимального воспроизводства (к сожалению, до сих пор ~ 180 линий ИЛ), и проверить, что составление IL с ILASM производит ех, что до сих пор демонстрирует эту проблему. Отладка с помощью Visual Studio или MDBG не просветил меня - я просто получить OutOfMemoryException без указания почему. Я готов поверить, мой IL недействительно каким-то образом, но peverify не указывает на проблему. Можно ли предположить, что проблема? // версия метаданных: v4.0.30319 .assembly ехЬегп mscorlib {.publickeytoken = (В7 7А 5С 56 19 34 89 Е0) // .z \ т.4 .. .ver 4: 0: 0: 0} .assembly ехЬегп система {.publickeytoken = (В7 7А 5С 56 19 34 E0 89) // .z \ V.4 .. .ver 4: 0: 0: 0} {.assembly Repro1 .ver 0: 0: 0: 0} .module Repro1 // MVID:
DJC_ksd
1

голосов
1

ответ
94

Просмотры

IL Испустите имя базового класса такого же, как унаследованный класс; protobuffer не принимает циклическое наследство

Я излучаемый код, который возвращает объект типа принятой в, где уведомление propertychange обернуто в виртуальные свойства, с модификацией отслеживанием для клиента. Этот новый тип будет распределяться между клиентом и сервером (сериализуются с помощью protobuf.net). Я ограничен не используя сторонние библиотеки, кроме использования protobuf.net. Проблема у меня в том, что, когда я пытаюсь сериализации список новых объектов (например, TypeA) с помощью protobuffer, я бегу в «Нечаянная подтипа: TypeA», и когда я пытаюсь добавить SubType в качестве модели для protobuffer с помощью RuntimeTypeModel, я бег в «циклические наследования не допускается», который protobuffer не принимает в это время, AFAIK. Я новичок в Reflection.Emit - есть способ ввести новый класс, излучаемого отличается от типа я излучающим, по крайней мере в названии? Я могу быть в состоянии преодолеть цикличность ограничения наследования в этом случае. Я хотел бы, чтобы избежать создания / копирования новых объектов. Так, например, выделяют новый объект как: NewTypeA -base TypeA вместо: TypeA -base TypeA -sub типа TypeA ИЛ-эмиттер: Использование: Тип aType = CreateProxy (TypeA); Activator.CreateInstance (aType); публичный статический тип CreateProxy (тип Type) {вар assmName = новый AssemblyName ( "DynamicProxyAssembly"); AB = AppDomain.CurrentDomain.DefineDynamicAssembly (assmName, AssemblyBuilderAccess.Run); Мб = _ab.DefineDynamicModule (assmName.Name); TypeBuilder TypeBuilder = mb.DefineType (type.Namespace + type.Name + "__proxy", TypeAttributes.Public, тип ""); typeBuilder.AddInterfaceImplementation (TypeOf (INotifyPropertyChanged)); FieldBuilder eventField = CreatePropertyChangedEvent (TypeBuilder); MethodBuilder raisePropertyChanged = CreateRaisePropertyChanged (TypeBuilder, eventField); MethodInfo isModifiedSetMethod = type.GetProperty ( "Modified") SetMethod. Еогеасп свойство в типе, где виртуальный метод обертывание с propertychangednotification ... Тип RET = typeBuilder.CreateType (); // это возвращает TypeA__proxy, полученное из себя (базового = TypeA__proxy). } // это возвращает TypeA__proxy, полученное из себя (базового = TypeA__proxy). } // это возвращает TypeA__proxy, полученное из себя (базового = TypeA__proxy). }
Option
1

голосов
1

ответ
304

Просмотры

ILGenerator Испустите: Нагрузка PropertyInfo имеет параметр метода

Я пытаюсь сделать этот код в IL, используя ILGenerator.Emit класс Foo {...} общественного класса TestClass {государственной статической силы тест () {тип T = TypeOf (Foo); Еогеасп (PropertyInfo р в t.GetProperties ()) {GenerateVar (p.PropertyInfo); }} Общественный статический объект GenerateVar (тип VAR) {если (вар == TypeOf (Int32)) {возвращают 5; } Еще если (вар == TypeOf (Char)) {возвращение 'а'; } Возвращать нуль; }} Это то, что я сделал до сих пор, и были некоторые осложнения: MethodInfo миль = TestClass.GetType () GetMethod ( "GenerateVar", BindingFlags.Public | BindingFlags.Instance);. ILGenerator генератора = mb.GetILGenerator (); LocalBuilder PropertyType; LocalBuilder TestClass = mb_gen.DeclareLocal (TypeOf (TestClass)); Еогеасп (PropertyInfo пи в t.GetProperties ()) {PropertyType = mb_gen.DeclareLocal (pi.PropertyType); // загружает в стек текущий PropertyType и метод класса generator.Emit (OpCodes.Ldloc, TestClass); generator.Emit (OpCodes.LdLoc, PropertyType); // вызов GenerateVar (тип VAR), чтобы получить PropertyType уаг generator.Emit (OpCodes.Callvirt, мили); } Это дает мне следующее исключение: -> Ожидаемый тип: System.Type, принимаемой: System.String System.String является тип недвижимости, которая определяется по формуле: pi.PropertyType; Что я делаю неправильно? заранее спасибо LocalBuilder TestClass = mb_gen.DeclareLocal (TypeOf (TestClass)); Еогеасп (PropertyInfo пи в t.GetProperties ()) {PropertyType = mb_gen.DeclareLocal (pi.PropertyType); // загружает в стек текущий PropertyType и метод класса generator.Emit (OpCodes.Ldloc, TestClass); generator.Emit (OpCodes.LdLoc, PropertyType); // вызов GenerateVar (тип VAR), чтобы получить PropertyType уаг generator.Emit (OpCodes.Callvirt, мили); } Это дает мне следующее исключение: -> Ожидаемый тип: System.Type, принимаемой: System.String System.String является тип недвижимости, которая определяется по формуле: pi.PropertyType; Что я делаю неправильно? заранее спасибо LocalBuilder TestClass = mb_gen.DeclareLocal (TypeOf (TestClass)); Еогеасп (PropertyInfo пи в t.GetProperties ()) {PropertyType = mb_gen.DeclareLocal (pi.PropertyType); // загружает в стек текущий PropertyType и метод класса generator.Emit (OpCodes.Ldloc, TestClass); generator.Emit (OpCodes.LdLoc, PropertyType); // вызов GenerateVar (тип VAR), чтобы получить PropertyType уаг generator.Emit (OpCodes.Callvirt, мили); } Это дает мне следующее исключение: -> Ожидаемый тип: System.Type, принимаемой: System.String System.String является тип недвижимости, которая определяется по формуле: pi.PropertyType; Что я делаю неправильно? заранее спасибо PropertyType); // загружает в стек текущий PropertyType и метод класса generator.Emit (OpCodes.Ldloc, TestClass); generator.Emit (OpCodes.LdLoc, PropertyType); // вызов GenerateVar (тип VAR), чтобы получить PropertyType уаг generator.Emit (OpCodes.Callvirt, мили); } Это дает мне следующее исключение: -> Ожидаемый тип: System.Type, принимаемой: System.String System.String является тип недвижимости, которая определяется по формуле: pi.PropertyType; Что я делаю неправильно? заранее спасибо PropertyType); // загружает в стек текущий PropertyType и метод класса generator.Emit (OpCodes.Ldloc, TestClass); generator.Emit (OpCodes.LdLoc, PropertyType); // вызов GenerateVar (тип VAR), чтобы получить PropertyType уаг generator.Emit (OpCodes.Callvirt, мили); } Это дает мне следующее исключение: -> Ожидаемый тип: System.Type, принимаемой: System.String System.String является тип недвижимости, которая определяется по формуле: pi.PropertyType; Что я делаю неправильно? заранее спасибо } Это дает мне следующее исключение: -> Ожидаемый тип: System.Type, принимаемой: System.String System.String является тип недвижимости, которая определяется по формуле: pi.PropertyType; Что я делаю неправильно? заранее спасибо } Это дает мне следующее исключение: -> Ожидаемый тип: System.Type, принимаемой: System.String System.String является тип недвижимости, которая определяется по формуле: pi.PropertyType; Что я делаю неправильно? заранее спасибо
Filipe G. Coelho
1

голосов
1

ответ
52

Просмотры

Переопределение сокращенные свойства в C #

Я понимаю, что когда я создаю сокращённое свойство в C #, это означает в поле, созданное для него, как только он компилируется. класс Hello {общественного BOOL Привет {множество; получить ; }} Мой вопрос: что произойдет, если сокращённое свойство является виртуальным, а затем переопределить: класс Hello {виртуальное общественное BOOL Привет {множество; получить ; }} // Класс и свойство не могут иметь такое же имя класса // Hi: Привет {класс Bonjour: Здравствуйте {переопределить общественное Hi Его {множество {} получить {возвращает истину; }}} Я переопределить виртуальную собственность полностью. Будет ли это по-прежнему генерировать поле при компиляции класса Hi, что я не буду в состоянии получить доступ больше? Спасибо.
edincanada
1

голосов
1

ответ
403

Просмотры

Calling generic method with Mono Cecil

Я хотел бы, чтобы ввести IL-код в методы, который вызывает общий метод (с типом возвращаемого значения и аргументов). общественности статической T MyGenericMethod (T genericArg, строка nonGenericArg) {// Есть ли что-то с genericArg вернуть genericArg; } Я могу назвать не являющиеся общие методы, но я понятия не имею, как вызвать универсальный метод. Мой вопрос, как я могу вводить этот общий вызов метода в метод? Пример неуниверсальных инъекции методы: 1, раскрывает сборку и получить общий метод нон данные DefaultAssemblyResolver распознаватель = новый DefaultAssemblyResolver (); resolver.AddSearchDirectory (assemblyResolverPath); AssemblyDefinition MyLibrary = AssemblyDefinition.ReadAssembly (assemblyPath, новые ReaderParameters () {AssemblyResolver = распознаватель}); MethodInfo writeLineMethod = TypeOf (отладки) .GetMethod ( "еЫп", Новый тип [] {TypeOf (строка)}); MethodReference WriteLine = myLibrary.MainModule.Import (writeLineMethod); 2, Инжектируйте метод "WriteLine" в выбраный метод: ILProcessor ilProcessor = method.Body.GetILProcessor (); Инструкция callWriteLine = ilProcessor.Create (OpCodes.Call, WriteLine); ilProcessor.InsertBefore (модули, "CALL"); ilProcessor.InsertBefore (модули, callWriteLine); Это приведет следующие дополнительные инструкции IL в методе выбраной: IL_0001: ldstr «CALL» IL_0006: называют недействительным [mscorlib] System.Console :: WriteLine (строка) Но в случае универсального метода, я должен получить этот IL: IL_0001 : ldc.i4.s 10 // 0x0a IL_0003: ldstr "CALL" IL_0008: вызов !! 0 / * int32 * / ReturnTestModule.ReturnTest ::
V. A.
1

голосов
1

ответ
66

Просмотры

IL emit with base class method invocation?

Как изменить этот IL-испускать-код для включения вызова метода в базовом классе в геттер и сеттер? Все, что я могу получить InvalidProgramException. FieldBuilder fieldBuilder = tb.DefineField ( "_" + PropertyName, PropertyType, FieldAttributes.Private); PropertyBuilder propertyBuilder = tb.DefineProperty (PropertyName, PropertyAttributes.HasDefault, PropertyType, NULL); MethodBuilder getPropMthdBldr = tb.DefineMethod ( "get_" + ИмениСвойства, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, PropertyType, Type.EmptyTypes); ILGenerator getIl = getPropMthdBldr.GetILGenerator (); getIl.Emit (OpCodes.Ldarg_0); //getIl.Emit(OpCodes.Call, baseType.GetMethod ( "Тест")); getIl.Emit (OpCodes.Ldfld, fieldBuilder); getIl.Emit (OpCodes.Ret); MethodBuilder setPropMthdBldr = tb.DefineMethod (» ILGenerator setIl = setPropMthdBldr.GetILGenerator (); Этикетка modifyProperty = setIl.DefineLabel (); Этикетка exitSet = setIl.DefineLabel (); setIl.MarkLabel (modifyProperty); //setIl.Emit(OpCodes.Call, baseType.GetMethod ( "Тест")); setIl.Emit (OpCodes.Ldarg_0); setIl.Emit (OpCodes.Ldarg_1); setIl.Emit (OpCodes.Stfld, fieldBuilder); setIl.Emit (OpCodes.Nop); setIl.MarkLabel (exitSet); setIl.Emit (OpCodes.Ret); propertyBuilder.SetGetMethod (getPropMthdBldr); propertyBuilder.SetSetMethod (setPropMthdBldr); ILGenerator setIl = setPropMthdBldr.GetILGenerator (); Этикетка modifyProperty = setIl.DefineLabel (); Этикетка exitSet = setIl.DefineLabel (); setIl.MarkLabel (modifyProperty); //setIl.Emit(OpCodes.Call, baseType.GetMethod ( "Тест")); setIl.Emit (OpCodes.Ldarg_0); setIl.Emit (OpCodes.Ldarg_1); setIl.Emit (OpCodes.Stfld, fieldBuilder); setIl.Emit (OpCodes.Nop); setIl.MarkLabel (exitSet); setIl.Emit (OpCodes.Ret); propertyBuilder.SetGetMethod (getPropMthdBldr); propertyBuilder.SetSetMethod (setPropMthdBldr); MarkLabel (exitSet); setIl.Emit (OpCodes.Ret); propertyBuilder.SetGetMethod (getPropMthdBldr); propertyBuilder.SetSetMethod (setPropMthdBldr); MarkLabel (exitSet); setIl.Emit (OpCodes.Ret); propertyBuilder.SetGetMethod (getPropMthdBldr); propertyBuilder.SetSetMethod (setPropMthdBldr);
Andreas Zita
2

голосов
0

ответ
17

Просмотры

Основы .NET IL / MSIL Оценка Stack

Не могу найти хороший ответ на эти вопросы. Вот что я думаю, что я знаю и что я нечеткий на. Оценка Стек представляет собой буфер памяти, как стек типа C (это стопка родной Int / size_t)? Оценка Стек элементы могут быть либо 32 или 64 бита (как же они смешиваются в одном стеке?) Ldloc_0 хранит локальную переменную в стеке оценки, но как если его больше, чем 64bits? Есть ли Ldloc_0 просто хранить PTRS на локальные переменные в стеке оценки? Есть объекты, хранящиеся в стеке оценки всегда либо указателей или примитивные значения? Если .maxsize 8 это значит (8 * size_t)? Если это так, как если бы я прочитал документы с указанием ее либо 32 или 64 Возьмем в качестве примера ниже. Означает ли это локальная переменная откладываются в стек оценки по ссылке PTR? общественный структура MyStruct {открытые длинные х, у, г; общественности статической MyStruct Foo () {MyStruct с; сх = 1; су = 2; CZ = 3; вернуться с; }} «Ldloc.0» явно хранится-структуру в стек оценки, но его также значительно больше, чем 64bits. Является ли ссылка хранится вместо этого? .class общественный последовательный запечатан beforefieldinit ANSI MyStruct расширяет [mscorlib] System.ValueType {// Fields .Field общественных int64 х .field общественного int64 у .Field общественных Int64 Z // Методы .method общественного hidebysig статического ValueType MyStruct Foo () CIL удалось { // Метод начинается в RVA 0x2050 // код размера 34 (0x22) .maxstack 2 .locals инициализации ([0] ValueType MyStruct, [1] ValueType MyStruct) IL_0000: NOP IL_0001: ldloca.s 0 IL_0003: ldc.i4. 1 IL_0004: conv.i8 IL_0005: stfld int64 MyStruct :: х IL_000a: ldloca.s 0 IL_000c: ldc.i4.2 IL_000d: conv.i8 IL_000e: stfld int64 MyStruct :: у IL_0013: ldloca.s 0 IL_0015: LDC. i4.3 IL_0016: conv.i8 IL_0017: stfld int64 MyStruct :: г IL_001c: ldloc.0 // Что на самом деле хранится здесь? IL_001d: stloc.1 IL_001e: уш IL_0020 IL_0020: ldloc.1 IL_0021: в отставке} // конец метода MyStruct :: Foo} // конец класса MyStruct 0 // Что на самом деле хранится здесь? IL_001d: stloc.1 IL_001e: уш IL_0020 IL_0020: ldloc.1 IL_0021: в отставке} // конец метода MyStruct :: Foo} // конец класса MyStruct 0 // Что на самом деле хранится здесь? IL_001d: stloc.1 IL_001e: уш IL_0020 IL_0020: ldloc.1 IL_0021: в отставке} // конец метода MyStruct :: Foo} // конец класса MyStruct
zezba9000
1

голосов
1

ответ
100

Просмотры

Закрепленные переменные в Mono.Cecil

Как я могу сделать локальную переменную прикрепленную с помощью Mono.Cecil?
moien
1

голосов
1

ответ
47

Просмотры

Генерация кода CIL байт на диске и в памяти

Я пишу компилятор, который предназначается для CIL (.Net) байт-код. Для той части, которая фактически генерирует байт-код, я мог бы написать ее с нуля, но это было бы удобно использовать существующую библиотеку, если это возможно. Мне нужно способность генерировать байт-код, как на диске (для обычного вида статической компиляции) и в памяти (генерации кода во время выполнения). Кроме того, возможность смотреть существующие сборки, по крайней мере, в той степени, чтобы быть в состоянии разрешить ссылки. Как я понимаю, есть три API, которые делают по крайней мере что-то вдоль этих линий, но это не сразу понятно, делают ли они именно то, что нужно: Отражение. Это, конечно, кажется, чтобы иметь возможность генерировать байт-код в памяти. Включается ли это способ создания полной сборки на диск? Mono.Cecil. Я думаю, что это будет подходящим? Их страница обновления говорит "
rwallace
1

голосов
1

ответ
83

Просмотры

CIL: Что означает ключевое слово «класс» означает, когда назначен «.Field»?

У меня есть определение поля: .field общественность статической initonly класса A.Program / «C» «9» Это часть вложенного типа генерируемого компилятор С #. Я хотел бы построить что-то подобное, используя ILGenerator.Emit. Я попытался посмотреть на C # в ILSpy, но она скрывает вложенный тип ( «Вложенные типы») для меня. Я ничего в ECMA-335 не найдено. Использование ILDASM / ILASM, я построил следующий код в надежде, что это даст мне C #: // версия Metadata: v4.0.30319 .assembly ехЬегп mscorlib {.publickeytoken = (В7 7А 5С 56 19 34 E0 89) // .z \ V.4 .. .ver 4: 0: 0: 0} .assembly Test {// --- следующий пользовательский атрибут добавляется автоматически, не раскомментировать ------- // .custom экземпляр недействительным [ mscorlib] System.Diagnostics.DebuggableAttribute ::. т е р (ValueType [mscorlib] System.Diagnostics.
Matt Jacobsen
1

голосов
1

ответ
153

Просмотры

Understanding CIL & the workings of ldelem.ref

Я хотел бы объяснить, что ldelem.ref делает. До сих пор у меня есть, что он загружает элемент с индексом на вершине стека как О. Что такое индекс? И я имею в виду, что тип O означает, что тип объекта останется бы то ни было, к примеру, если это строка останется строкой. У меня есть пример здесь ниже некоторого кода я работаю, и я был бы очень признателен некоторое понимание. Я заметил, что я считаю, что я знаю. Так что в данном случае является то, что .locals инициализации (строка v_0, BOOL V_1, строка V_2, BOOL V_3, строка V_4, строка V_5, строка V_6) // Заявленный 6 переменных .try {IL_0000: NOP IL_0001: NOP // ничего не делает - Отладка сборки IL_0002: ldarg.0 // Нагрузки Аргумент 0 в память / стек IL_0003: ldc.i4. ссылка здесь делает? Является ли op_Equality сравнения строки «Del» с содержимым переменного 0? Я беру это, что после того, как вызов будет сделано, логическое значение операции затем сохраняется в верхней части стека и stloc.1 выталкивает логическое значение и сохраняет его в переменной 1, то ldloc.1 нагрузки этой переменной на стек и brfalse.s проверяет значение Bool и если ложно «прыгает» на IL_004e, это так?
0siris

Просмотр дополнительных вопросов