SecurityException: ECall methods must be packaged

2019-01-25 01:29发布

问题:

I have a (C#) function similar to the following.

private static bool SpecialCase = false;

public void Foo()
{
    if (SpecialCase)
    {
        InternalMethod();
        return;
    }

    Console.WriteLine();
}

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void InternalMethod();

When I execute this with the .NET Framework 4 inside the debugger, the method successfully prints blank line to the console and returns. When I execute it outside the debugger, it throws an exception with the following message:

System.Security.SecurityException: ECall methods must be packaged into a system module.

It appears the exception is thrown when the JIT compiler compiles the method as opposed to when (if) InternalMethod is called. Is there anything I can do (e.g. attributes) to tell the CLI to either not throw the SecurityException, or delay the exception until the method is actually called?

Side note on the use case: The SpecialCase field is effectively false when running with Microsoft .NET Framework, and true when running under a different (specific) implementation of the CLI. When running under the Microsoft .NET Framework, the call to InternalMethod is effectively unreachable.

回答1:

You may want to check the compiler directives as a possible option. Unlike using a run-time "if", this will determine whether the call is included in the compiled code at all, rather than always compiling it into the code and trying to determine whether to call it at run-time (which is too late, based on your analysis).

Your use-case seems like a testing/validation scenario, which means that you don't need it compiled into the code except when the internal call will actually be made.

Note that if your use-case involves a non-.NET runtime, you should provide more information since that could drastically change the correct answer.



回答2:

Add attribute [ComImport] to your class declaration