這個文件可以引導你如何通過CoreRT生成一個原生標準的系統動態庫讓其他程式語言呼叫. CoreRT 可以構建靜態庫, 這些庫可以在編譯時連結或者也可以構建執行時所需的共享庫,
建立一個支援CoreRT的 .NET Core 類庫專案
使用 dotnet new console -o NativeLibrary
建立一個.NET Core類庫專案並參考Hello world 示例為專案加入 CoreRT 的支援.
生成靜態庫
> dotnet publish /p:NativeLib=Static -r <RID> -c <Configuration>
<Configuration>
是你專案的配置 (比如Debug 或者 Release) 和 <RID>
是執行時標識(可以是 win-x64, linux-x64, osx-x64其中之一).比如,你想釋出一個 release 配置並且是Windows 64位動態庫的時候命令列你可以這麼寫:
> dotnet publish /p:NativeLib=Static -r win-x64 -c release
上面的命令將刪掉一個靜態庫 (Windows .lib
, OSX/Linux .a
) 用 ./bin/[configuration]/netstandard2.0/[RID]/publish/
資料夾並將有一個同名資料夾在你的原始碼資料夾呈現。
生成共享庫
> dotnet publish /p:NativeLib=Shared -r <RID> -c <Configuration>
上面的命令將刪掉共享庫 (Windows .dll
, OSX .dylib
, Linux .so
) 在 ./bin/[configuration]/netstandard2.0/[RID]/publish/
資料夾並將有一個同名資料夾在你的原始碼中呈現.生成共享庫在Linux上目前截止2018年12月6日不能正常工作, 詳情檢視 #4988.
匯出方法
針對一個 C# 方法再本地原生動態庫被外部程式呼叫, 必須要使用 [NativeCallable]
屬性進行匯出. 首先定義NativeCallable
類在哪i的專案中,請檢視這裡.本地定義 NativeCallable
是一個臨時解決方法,正式釋出的時候會新增到.Net Core 內.
下一步,在要匯出的方法上使用 EntryPoint
和 CallingConvention
屬性:
[NativeCallable(EntryPoint = "add", CallingConvention = CallingConvention.StdCall)]
public static int Add(int a, int b)
{
return a + b;
}
在原生動態庫生成後, C# 的Add
方法被匯出為add
函式功其他語言呼叫. 在決定要匯出的託管方法時, 需要考慮以下一些限制:
- 匯出方法必須是靜態.
- 匯出方法只能是原生可接收或值型別(比如結構 ),他們必須封裝所有引用型別引數 .
- 無法從常規託管 c# 程式碼呼叫匯出的方法, 會有發生異常.
- 匯出的方法不能使用常規的 C# 異常捕獲,必須使用錯誤程式碼替換.
引用
真實案例如何使用 CoreRT編寫用於Rust的原始動態庫: https://medium.com/@chyyran/calling-c-natively-from-rust-1f92c506289d