Вызов глобальной функции ILAsm из кода C#

Предположим, у меня есть библиотека ILAsm со следующим кодом:

.assembly extern mscorlib{}
.assembly TestMe{}
.module TestMe.dll
.method public static void PrintMe() cil managed 
{
    ldstr "I'm alive!"
    call void [mscorlib]System.Console::WriteLine(string)
    ret
}

Как я могу вызвать глобальную функцию PrintMe() из кода C#?


person user2341923    schedule 05.10.2013    source источник
comment
Просто добавьте ссылку на сборку, созданную из этого кода. Теперь все это работает так же, как вы знакомы с C#.   -  person Hans Passant    schedule 05.10.2013
comment
Если я просто добавлю ссылку на .dll, мой код .cs не увидит функцию PrintMe().   -  person user2341923    schedule 05.10.2013
comment
Вы еще не написали правильный IL, используйте ildasm.exe, чтобы увидеть, как выглядит хороший IL. Методы должны быть частью класса.   -  person Hans Passant    schedule 05.10.2013
comment
Моя dll действительна. Глобальные поля и методы разрешены в .Net и используются, например. управляемым C++.   -  person user2341923    schedule 05.10.2013
comment
Это не так. Используйте ildasm.exe на сборке C++/CLI, и вы увидите, что он добавляет бесплатные функции в качестве методов к скрытому классу <Module>.   -  person Hans Passant    schedule 05.10.2013
comment
‹Модуль› также был добавлен в мой PrintMe(). Можно ли сказать, что он тоже стал частью класса?   -  person user2341923    schedule 05.10.2013
comment
Ilasm.exe может делать это по умолчанию, никогда не пытался намеренно сделать это неправильно. Если вы увидите это тогда, да, я бы предположил, что он автоматически следовал правилам CLR и гарантировал, что метод станет частью класса. Этот класс <Module> является закрытым, поэтому вы не можете получить к нему доступ в С#. Вместо этого просто объявите публичный класс.   -  person Hans Passant    schedule 05.10.2013
comment
Да, действительно, у ilasm нет другого выбора, кроме как использовать класс особого случая <Module>, как описано в ECMA-335 II.10.8 Глобальные поля и методы.   -  person user2341923    schedule 05.10.2013


Ответы (2)


Вы можете через отражение.. но не очень полезным способом:

var module = Assembly.LoadFile("path_to_dll.dll").GetModules()[0]; 
// the first and only module in your assembly
var method = module.GetMethod("PrintMe");

method.Invoke(null, 
              BindingFlags.Public | BindingFlags.Static, 
              null, 
              null, 
              CultureInfo.CurrentCulture); // Prints "I'm alive!" to console.
person Simon Whitehead    schedule 05.10.2013

Вы не можете, насколько я знаю. C# «знает» только о методах, объявленных в типах, а не на верхнем уровне. Переместите свой метод в тип.

person Jon Skeet    schedule 05.10.2013