Стандартная библиотека .NET зависит от неуправляемых DLL файлов?

Просто из любопытства, сама инфраструктура .NET зависит от любых неуправляемых DLL файлов при доступе к стандартной библиотеке? Например, я вызываю метод A и - под капотом - этот метод A или любой другой метод внутри этого метода A выполняет PInvoke против неуправляемой библиотеки DLL?

Ответ 1

Да, библиотеки .Net часто используют неуправляемые функции. Есть два типа неуправляемых функций (которые я знаю), которые может вызвать библиотека: либо методы из самой Framework, либо методы из какой-либо другой DLL (с ​​использованием PInvoke).

Методы, реализованные в рамках, отмечены [MethodImpl(MethodImplOptions.InternalCall)]. Те, которые поступают из других неуправляемых библиотек DLL, отмечены [DllImport].

В моей версии только mscorlib.dll существует 7241 методов, которые реализованы внутри структуры (например, получателя string.Length) и 535, которые из некоторой неуправляемой библиотеки DLL (многие из них находятся во внутреннем классе Win32Native).

Ответ 2

Да, конечно, структура содержит бесчисленные вызовы базового API Windows. Посмотрите на декомпилированный код файла File.Move:

[SecuritySafeCritical]
public static void Move(string sourceFileName, string destFileName)
{
    if (sourceFileName == null)
    {
        throw new ArgumentNullException("sourceFileName", Environment.GetResourceString("ArgumentNull_FileName"));
    }
    if (destFileName == null)
    {
        throw new ArgumentNullException("destFileName", Environment.GetResourceString("ArgumentNull_FileName"));
    }
    if (sourceFileName.Length == 0)
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "sourceFileName");
    }
    if (destFileName.Length == 0)
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destFileName");
    }
    string fullPathInternal = Path.GetFullPathInternal(sourceFileName);
    new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, new string[] { fullPathInternal }, false, false).Demand();
    string dst = Path.GetFullPathInternal(destFileName);
    new FileIOPermission(FileIOPermissionAccess.Write, new string[] { dst }, false, false).Demand();
    if (!InternalExists(fullPathInternal))
    {
        __Error.WinIOError(2, fullPathInternal);
    }
    if (!Win32Native.MoveFile(fullPathInternal, dst))
    {
        __Error.WinIOError();
    }
}

Как вы можете видеть, в конце игры у нас есть вызов Win32Native.MoveFile. который определяется как...

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
internal static extern bool MoveFile(string src, string dst);

Ответ 3

В библиотеке классов Framework используется много P/Invokes для разных DLL-библиотек Windows. Например, см. Внутренний класс Microsoft.Win32.Win32Native в mscorlib, который содержит много DllImports. Например, System.IO.FileStream.Read в конечном счете использует Win32.ReadFile.

Ответ 4

Если вы посмотрите на перечисление System.Runtime.CompilerServices.MethodImplOptions, у него есть флаг Unmanaged. Не могу найти, где он используется.

namespace System.Runtime.CompilerServices
{
  [Flags]
  [ComVisible(true)]
  [Serializable]
  public enum MethodImplOptions
  {
    Unmanaged = 4,
    ForwardRef = 16,
    PreserveSig = 128,
    InternalCall = 4096,
    Synchronized = 32,
    NoInlining = 8,
    NoOptimization = 64,
  }
}