出于好奇,.NET框架本身在访问标准库时是否依赖于任何非托管DLL?例如,我调用方法A和-under-hood方法A或方法A中的任何其他方法对非托管DLL执行PInvoke?
答案 0 :(得分:3)
是的,当然,框架包含对底层Windows API的无数调用。 查看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);
答案 1 :(得分:3)
是的,.Net库大量使用非托管功能。库可以调用两种类型的非托管函数(我知道):来自Framework本身的方法,或来自其他DLL的方法(使用PInvoke)。
框架中实现的方法标有[MethodImpl(MethodImplOptions.InternalCall)]
。那些来自其他非托管DLL的标记为[DllImport]
。
在我的mscorlib.dll版本中,有7241个方法由框架内部实现(例如string.Length
的getter)和535来自某些非托管DLL(其中许多是在内部class Win32Native
)。
答案 2 :(得分:0)
框架类库对不同的Windows API DLL使用了大量的P / Invokes。例如,请参阅mscorlib中包含许多DllImports的内部类Microsoft.Win32.Win32Native。例如,System.IO.FileStream.Read最终使用Win32.ReadFile。
答案 3 :(得分:0)
如果查看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,
}
}