Asked by Kevin Lanos. Answered by the Wonk on March 5, 2003
A.
When a normal call is made into unmanaged code from managed .NET code, a stack walk of all assemblies is performed to make sure that all of them have permission to make calls into unmanaged code. For example, an assembly that's been downloaded from the Intranet is not going to have such permissions by default. This stack walk is .NET's way to make sure that partially-trusted code can't ask fully-trusted code to do something bad on its behalf.
However, as you might imagine, taking that stack walk takes time. That's especially true in the case of making unmanaged calls because a great deal of the .NET Framework Class Library (FCL) is merely a wrapper around existing unmanaged code, so the performance overhead of making all of those stack walks all the time would be crushing. Towards that end, the .NET guys built an optimization: the SuppressUnmanagedCodeSecurity attribute.
The purpose of the SuppressUnmanagedCodeSecurity attribute is to allow you to write a class, method or interface that makes calls into managed code but that skips the stack walk. Of course, the code that does this needs to make double sure that it can't be made to do anything bad, but while that can often be developer-intensive, it's not generally run-time intensive when compared with the stack walk.
And why can't the SuppressUnmanagedCodeSecurity attribute be applied to a structure? Because where it's defined, it's only allowed to be applied to classes, methods and interfaces:
[AttributeUsage(
AttributeTargets.Class |
AttributeTargets.Method |
AttributeTargets.Interface)]
public sealed class SuppressUnmanagedCodeSecurityAttribute : Attribute {...}
The real question (and I'm sure that this is the question you're asking), is why didn't the security guys let this attribute be applied to structures along with classes, interfaces and methods? My guess is that when the applied the optimization, the only usages in the FCL that needed it were ones that applied it classes, methods and interfaces. Since this can be a dangerous optimization to apply, I'm sure that they felt that narrowing it as much as possible was a good thing, which left structures out. If you find yourself needing this optimization for structures, inside the structure, build yourself a nested class that makes the actual calls to unmanaged code:
struct MySecureStruct {
public void CallUnmanagedCode() {
MySecureHelperClass.CallUnmanagedCode();
}
[System.Security.SuppressUnmanagedCodeSecurityAttribute()]
class MySecureHelperClass {
public static void CallUnmanagedCode() {
}
}
}
Of course, any application of the SuppressUnmanagedCodeSecurity attribute requires intensive scrubbing to ensure that you're not opening up a security hole.