C# internal static extern with InternalCall attribute - internal or external?
Asked Answered
A

2

37

In another question I asked, a comment arose indicating that the .NET framework's Array.Copy method uses unmanaged code. I went digging with Reflector and found the signature one of the Array.Copy method overloads is defined as so:

[MethodImpl(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable);

After looking at this, I'm slightly confused. The source of my confusion is the extern modifier which means (MSDN link):

The extern modifier is used to declare a method that is implemented externally.

However, the method declaration is also decorated with a MethodImplOptions.InternalCall attribute, which indicates (MSDN link):

Specifies an internal call. An internal call is a call to a method that is implemented within the common language runtime itself.

Can anyone explain this seemingly apparent contradiction?

Asphyxiate answered 31/7, 2009 at 9:10 Comment(0)
M
56

I would have just commented on leppie's post, but it was getting a bit long.

I'm currently working on an experimental CLI implementation. There are many cases where a publicly exposed method (or property) can't be implemented without knowledge of how the virtual machine is implemented internally. One example is OffsetToStringData, which requires knowledge of how the memory manager allocates strings.

For cases like this, where there is no C# code to express the method, you can treat each call to the method in a special way internal to the JIT process. As an example here, replacing the call byte code with a ldc.i4 (load constant integer) before passing it to the native code generator. The InternalCall flag means "The body of this method is treated in a special way by the runtime itself." There may or may not be an actual implementation - in several cases in my code the call is treated as an intrinsic by the JIT.

There are other cases where the JIT may have special information available that allows heavy optimization of a method. One example is the Math methods, where even though these can be implemented in C#, specifying InternalCall to make them effectively intrinsics has significant performance benefits.

In C#, a method has to have a body unless it is abstract or extern. The extern means a general "You can call this method from C# code, but the body of it is actually defined elsewhere.". When the JIT reaches a call to an extern method, it looks up where to find the body and behaves in different ways per the result.

  • The DllImport attribute instructs the JIT to make a P/Invoke stub to call a native code implementation.
  • The InternalCall flag instructs the JIT to treat the call in a self-defined way.
  • (There are some others, but I don't have examples off the top of my head for their use.)
Mejia answered 31/7, 2009 at 9:37 Comment(0)
S
19

InternalCall means provided by the framework.

extern says you are not providing code.

extern can be used in 2 general situations, like above, or with p/invoke.

With p/invoke, you simply tell the method where to get the implementation.

Slipcover answered 31/7, 2009 at 9:12 Comment(2)
@Slipcover - I wish I could mark both yours and 280Z28's answers as accepted since you're both correct. However, I feel that 280Z28's answer spells it out a little more and helped me to understand better, however, thanks a lot for your effort.Asphyxiate
No problem, I have enough points already, I'll give him some more too :)Slipcover

© 2022 - 2024 — McMap. All rights reserved.