SecurityException: методы ECall должны быть упакованы в системный модуль
У меня есть функция (С#), аналогичная следующей.
private static bool SpecialCase = false;
public void Foo()
{
if (SpecialCase)
{
InternalMethod();
return;
}
Console.WriteLine();
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void InternalMethod();
Когда я выполняю это с .NET Framework 4 внутри отладчика, метод успешно печатает пустую строку на консоли и возвращает. Когда я выполняю его вне отладчика, он выдает исключение со следующим сообщением:
System.Security.SecurityException: ECall methods must be packaged into a system module.
Похоже, что исключение возникает, когда компилятор JIT компилирует метод, а не когда (if) InternalMethod
вызывается. Есть ли что-нибудь, что я могу сделать (например, атрибуты), чтобы сообщить CLI либо не выкидывать SecurityException
, либо задерживать исключение до тех пор, пока фактически не будет вызван метод?
Боковое примечание в прецеденте: поле SpecialCase
является фактически ложным при работе с Microsoft.NET Framework и истинно при работе под другой (конкретной) реализацией CLI. При работе в Microsoft.NET Framework вызов InternalMethod
является недоступным.
Ответы
Ответ 1
Вы можете проверить директивы компилятора как возможный вариант.
В отличие от использования времени выполнения "если", это определит, включен ли вызов в скомпилированный код, а не всегда компилирует его в код и пытается определить, следует ли его вызывать во время выполнения (что слишком поздно, основанный на вашем анализе).
Ваш прецедент выглядит как сценарий тестирования/проверки, а это значит, что он не нуждается в компиляции в код, кроме случаев, когда внутренний вызов будет выполнен.
Обратите внимание, что если ваш случай использования включает в себя не .NET-среду выполнения, вы должны предоставить дополнительную информацию, поскольку это может кардинально изменить правильный ответ.
Ответ 2
Добавить атрибут [ComImport]
в объявление класса