.Net Native程序生成的过程
起因
在.Net 6 生成Native库,让C/C++调用 一文中,将.Net程序生成为Native(原生=>操作系统默认支持的格式可执行程序)程序,说Native程序就得说操作系统支持的可执行程序:- Windows可执行程序类型是PE(有exe和dll(这个不包含.Net程序的exe和dll),lib)
- Linux可执行程序类型是ELF(so和a)
为什么要说这些,是因为Native的过程,就是将.Net exe和dll转为操作系统可执行程序的远程.
C/C++生成可执行程序的过程
因为操作系统是用C语言编写(还有汇编,即使在.Net CoreCLR和JVM源码中,还能看到使用汇编的地方,如果没有记错的话Go语言的源码也有汇编),所以C语言生成的可执行程序,就是操作系统默认可执行程序,C语言的源文件到可执行程序,简单看为两个步骤;- 源文件编译为目标文件(*.c生成obj(Windows)和o(Linux)
- 将多个目标文件链接成可执行程序

.Net Native过程
Native的过程是将.Net的exe/dll和.Net 运行时生成一个目标文件(obj),在和一个C/C++程序(链接目标文件).最终生成Native程序.
在在.Net 6 生成Native库,让C/C++调用-秋风技术 (qiufengblog.com) ,使用的HelloWorld是官方的示例.这里不讲怎么使用了,在我们使用publish生成Native程序后.
在HelloWorld的根目录,可以看到有一个obj目录.至于上面为什么说将.Net程序生成obj(目标文件)的原因,就在这个目录.具体路径: obj/Debug/net6.0/win-x64/native/
在*.ilc.rsp文件:
obj\Debug\net6.0\win-x64\HelloWorld.dll
-o:obj\Debug\net6.0\win-x64\native\HelloWorld1.obj //生成目标文件
// -r xxx引用.Net程序所需的程序,因为引用太多,这里裁剪很多引用
-r:E:\nuget\packages\microsoft.netcore.app.runtime.win-x64\6.0.0\runtimes\win-x64\lib\net6.0\System.Security.Cryptography.Encoding.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\framework\System.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\framework\System.Drawing.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\framework\System.Drawing.Primitives.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\framework\System.Dynamic.Runtime.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\framework\System.Xml.XPath.XDocument.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\framework\WindowsBase.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\System.Private.CoreLib.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\System.Private.DisabledReflection.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\System.Private.Interop.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\System.Private.Reflection.Core.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\System.Private.Reflection.Execution.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\System.Private.Reflection.Metadata.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\System.Private.StackTraceMetadata.dll
-r:E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\System.Private.TypeLoader.dll
--targetarch:x64 //生成64位程序
-g
--initassembly:System.Private.CoreLib
--initassembly:System.Private.StackTraceMetadata
--initassembly:System.Private.TypeLoader
--initassembly:System.Private.Reflection.Execution
--initassembly:System.Private.Interop
--appcontextswitch:Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability=true
--appcontextswitch:System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization=false
--appcontextswitch:System.Resources.ResourceManager.AllowCustomResourceTypes=false
--appcontextswitch:System.Runtime.InteropServices.BuiltInComInterop.IsSupported=false
--appcontextswitch:System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting=false
--appcontextswitch:System.Runtime.InteropServices.EnableCppCLIHostActivation=false
--appcontextswitch:System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization=false
--appcontextswitch:System.StartupHookProvider.IsSupported=false
--appcontextswitch:System.Threading.Thread.EnableAutoreleasePool=false
--appcontextswitch:System.Text.Encoding.EnableUnsafeUTF7Encoding=false
--directpinvoke:System.IO.Compression.Native
--directpinvokelist:E:\nuget\packages\microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\build\WindowsAPIs.txt
--feature:Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability=true
--feature:System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization=false
--feature:System.Resources.ResourceManager.AllowCustomResourceTypes=false
--feature:System.Runtime.InteropServices.BuiltInComInterop.IsSupported=false
--feature:System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting=false
--feature:System.Runtime.InteropServices.EnableCppCLIHostActivation=false
--feature:System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization=false
--feature:System.StartupHookProvider.IsSupported=false
--feature:System.Threading.Thread.EnableAutoreleasePool=false
--feature:System.Text.Encoding.EnableUnsafeUTF7Encoding=false
--stacktracedata
--scanreflection
在link.rsp文件:
"obj\Debug\net6.0\win-x64\native\HelloWorld.obj" //链接目标文件
/OUT:"bin\Debug\net6.0\win-x64\native\HelloWorld.exe" //生成可执行程序
/LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\ATLMFC\lib\x64"
/LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64"
/LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64"
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\ucrt\x64"
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22000.0\\um\x64"
"obj\Debug\net6.0\win-x64\native\HelloWorld.res"
"E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\bootstrapper.lib" //引用需要.Net Runtime静态库
"E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\Runtime.WorkstationGC.lib"
"E:\nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\sdk\System.IO.Compression.Native.Aot.lib"
"advapi32.lib" //引用所需要的操作系统的静态库
"bcrypt.lib"
"crypt32.lib"
"iphlpapi.lib"
"kernel32.lib"
"mswsock.lib"
"ncrypt.lib"
"normaliz.lib"
"ntdll.lib"
"ole32.lib"
"oleaut32.lib"
"secur32.lib"
"user32.lib"
"version.lib"
"ws2_32.lib"
/NOLOGO /MANIFEST:NO
/DEBUG
/INCREMENTAL:NO
/SUBSYSTEM:CONSOLE //指定生成控制台程序
/ENTRY:wmainCRTStartup //指定程序的入口函数为wmainCRTStartup
/NATVIS:"E:\nuget\packages\microsoft.dotnet.ilcompiler\7.0.0-alpha.1.21562.1\build\CoreRTNatVis.natvis"
*.ilc.rsp(将.Net程序编译为目标文件的过程),link.rsp文件(链接obj文件到可执行的过程)
秋风
2021-12-05