Jenter Алекс
Шрифт:
namespace MyLib {
public interface ICalculator {
double Add(double n, ref double round, out double overflow);
}
}
Код, создающий сборку, реализован на C#, языке, похожем на C++ или Java. Мы надеемся, что у вас не возникнет проблем с пониманием кода:
using System;
using System.Reflection;
using System.Reflection.Emit;
public class emititf {
// Точка входа программы (объектно-ориентированный аналог функции main в С/C++)
public static int Main(String[] argv) {
// Создаем новую сборку AssemblyBuilder ab = DefineNewAssembly;
// Создаем определение нового интерфейса ICalculator внутри новой сборки
TypeBuilder tb = DefineICalculator(ab);
// Добавляем описание метода "Add" к описанию интерфейса
ICalculator MethodBuilder method = DefineAddMethod(tb);
// Добавляем описание параметров
DefineAddParameters(method);
// Создаем тип
Type t = tb.CreateType;
// Записываем сборку в файл "mylib.dll"
ab.Save("mylib.dll");
return 0;
}
// Создает сборку с именем "mylib"
static AssemblyBuilder DefineNewAssembly {
// Новая сборка создается в рамках текущего AppDomain-а
AppDomain current = AppDomain.CurrentDomain;
// Новая сборка нуждается в имени. Назначаем ей не строгое имя!
AssemblyName an = new AssemblyName;
an.Name = "mylib";
// DefineDynamicAssembly завершает работу по созданию сборки
return current.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save);
}
// Создает новое описание интерфейса с именем "MyLib.ICalculator"
static TypeBuilder DefineICalculator(AssemblyBuilder ab) {
// Все описания типов находятся в модуле, определенном для нашей сборки
ModuleBuilder mb = ab.DefineDynamicModule("mylib.dll", "mylib.dll");
// Все описания интерфейсов должны быть помечены как Interface и Abstract
TypeAttributes attrs = TypeAttributes.Interface | TypeAttributes.Abstract;
// public-интерфейсы должны быть также помечены как
Public attrs |= TypeAttributes.Public;
// DefineType завершает работу по созданию описания для интерфейса
return mb.DefineType("MyLib.ICalculator", attrs);
}
// Создает новое описание методов "double Add(double, ref double, out double)"
static MethodBuilder DefineAddMethod(TypeBuilder itf) {
// Методы интерфейса должны быть помечены как abstract, virtual и public
MethodAttributes attrs = MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual;
// Метод определяется по имени и описанию (его параметрам)
// Создаем описание возвращаемого значения
Type resultType = typeof(double);
// Создаем описание параметров
Type[] paramTypes = new Type[] {
typeof(double), Type.GetType("System.Boolean&"), Type.GetType("System.Boolean&")
};
// DefineMethod завершает работу по созданию описания метода
return itf.DefineMethod("Add", attrs, resultType, paramTypes);
}
// Задает имя параметров и их последовательность
static void DefineAddParameters(MethodBuilder method) {
// 1-й и 2-й параметры не нуждаются в специальных атрибутах
method.DefineParameter(1, ParameterAttributes.None, "n");