日韩欧美人妻无码精品白浆,夜夜嗨AV免费入口,国产欧美官网在线看,高校回应聋哑女生因长相完美被质疑

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C# NativeAOT 多平臺下的函數(shù)導(dǎo)出

freeflydom
2025年6月9日 9:22 本文熱度 40

一:背景

1. 講故事

昨晚訓(xùn)練營里有一位朋友提到一個(gè)問題,說 C# AOT程序能否編譯為一個(gè)dll,供其他語言調(diào)用,其實(shí)這個(gè)是完全沒有問題的,也確實(shí)我的的文章體系中沒有涉及到這塊,那今天就補(bǔ)充完整吧。

二:NativeAOT 函數(shù)導(dǎo)出

1. 簡單的案例

在 C 中我相信很多人都知道用 dllexport 進(jìn)行函數(shù)導(dǎo)出,如下所示:


extern "C"
{
	_declspec(dllexport) void ComplexCalculation();
}

在 C# 中其實(shí)也差不多,用 UnmanagedCallersOnly 特性替代即可,接下來創(chuàng)建一個(gè) C# 的類庫,參考代碼如下:


internal class ExportMethods
{
    [UnmanagedCallersOnly(EntryPoint = "ComplexCalculation")]
    public static int ComplexCalculation(int a, int b, IntPtr stringInput)
    {
        try
        {
            // 1. 處理字符串參數(shù)(從非托管代碼傳入的 char*)
            string? inputStr = Marshal.PtrToStringAnsi(stringInput);
            Console.WriteLine($"Input string: {a},, {inputStr}");
            // 2. 復(fù)雜計(jì)算邏輯
            int result = a + b;
            if (inputStr?.ToLower() == "double")
            {
                result *= 2;
            }
            return result;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return -1;
        }
    }
}

在 csproject 中追加最后二行,其中的 <NativeLib>Shared</NativeLib> 表示可以生成動態(tài)鏈接庫,即 windows 上的 .dll 以及 linux 上的 .so 文件。


<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
		<TargetFramework>net8.0</TargetFramework>
		<ImplicitUsings>disable</ImplicitUsings>
		<Nullable>enable</Nullable>
		<Platforms>AnyCPU;x86</Platforms>
	  <!--追加的 ?-->
		<PublishAot>true</PublishAot>
		<NativeLib>Shared</NativeLib>
	</PropertyGroup>
</Project>

配置好之后就可以用 dotnet publish 發(fā)布為 windows 的原生動態(tài)鏈接庫,參考如下:


PS D:\skyfly\20.20250116\src\Example\Example_20_1_1> dotnet publish -r win-x64  -o D:\testdump
還原完成(0.3)
  Example_20_1_1 已成功 (1.5) → D:\testdump\
在 2.1 中生成 已成功
PS D:\skyfly\20.20250116\src\Example\Example_20_1_1>

生成好 dll 之后可以用 PPEE 工具觀察下 export 表,打開之后果然有了 ComplexCalculation 函數(shù)。

接下來大家可以把這個(gè) dll 提供給 C 或者 C# 去調(diào)用,只要 PE頭里有,怎么開心怎么玩。

這里新建一個(gè) Example_20_1_6 的 C# 控制臺程序,使用傳統(tǒng)的 DllImport 導(dǎo)入外部方法,就像以前引入C的外部方法一樣,參考代碼如下:


internal class Program
{
    [DllImport("Example_20_1_1", CallingConvention = CallingConvention.StdCall)]
    extern static int ComplexCalculation(int a, int b, IntPtr stringInput);
    static void Main(string[] args)
    {
        Console.WriteLine("準(zhǔn)備調(diào)用原生方法...");
        // 1. 將托管字符串轉(zhuǎn)換為非托管指針
        IntPtr stringPtr = Marshal.StringToHGlobalAnsi("double");
        try
        {
            // 2. 調(diào)用原生方法
            int result = ComplexCalculation(10, 20, stringPtr);
            Console.WriteLine($"調(diào)用完成,結(jié)果: {result}");
        }
        finally
        {
            // 3. 釋放非托管內(nèi)存
            Marshal.FreeHGlobal(stringPtr);
        }
    }
}

將 Example_20_1_1.dll 拷貝到當(dāng)前的bin目錄下,運(yùn)行程序之后,一切ok,截圖如下:

2. linux 上的投放

剛才只是在 windows 平臺上的演示,接下來試部署到 ubuntu 上,正常情況下你可能不會那么一帆風(fēng)順,不是缺少這個(gè)庫就是那個(gè)庫,比如下面的報(bào)錯。


root@ubuntu2404:/data2/Example_20_1_1#  dotnet publish -r linux-x64 -o ./dll
MSBuild version 17.8.22+bfbb05667 for .NET
  Determining projects to restore...
  Restored /data2/Example_20_1_1/Example_20_1_1.csproj (in 27.42 sec).
  Example_20_1_1 -> /data2/Example_20_1_1/bin/Release/net8.0/linux-x64/Example_20_1_1.dll
  Generating native code
  /usr/bin/ld.bfd: cannot find -lz: No such file or directory

上面就是典型的缺少 zlib 包,安裝一下即可,所以大家也是根據(jù)報(bào)錯一個(gè)一個(gè)解決,最終肯定會走出迷霧。


root@ubuntu2404:/data2/Example_20_1_1# sudo apt update && sudo apt install zlib1g-dev
root@ubuntu2404:/data2/Example_20_1_1# dotnet publish -r linux-x64 -o ../
MSBuild version 17.8.22+bfbb05667 for .NET
  Determining projects to restore...
  All projects are up-to-date for restore.
  Example_20_1_1 -> /data2/Example_20_1_1/bin/Release/net8.0/linux-x64/Example_20_1_1.dll
  Example_20_1_1 -> /data2/
root@ubuntu2404:/data2/Example_20_1_1# ls -lh ../
total 4.0M
drwxr-xr-x 5 root root 4.0K May 28 10:20 Example_20_1_1
-rw-r--r-- 1 root root 1.5M May 28 10:26 Example_20_1_1.so
-rwxr-xr-x 1 root root 2.5M May 28 10:26 Example_20_1_1.so.dbg
-rw-r--r-- 1 root root    0 May 28 10:18 app.c

有了這個(gè) so 文件后,接下來我們新建一個(gè) c文件,參考代碼如下:


#include <stdio.h>
#include <dlfcn.h> // 動態(tài)加載庫
int main()
{
    void *handle = dlopen("./Example_20_1_1.so", RTLD_LAZY);
    
    if (!handle)
    {
        fprintf(stderr, "Error: %s\n", dlerror());
        return 1;
    }
    // 獲取函數(shù)指針
    int (*ComplexCalculation)(int, int, const char *) =
        (int (*)(int, int, const char *))dlsym(handle, "ComplexCalculation");
    if (!ComplexCalculation)
    {
        fprintf(stderr, "Error: %s\n", dlerror());
        dlclose(handle);
        return 1;
    }
    // 調(diào)用函數(shù)
    int result = ComplexCalculation(10, 20, "double");
    printf("Result: %d\n", result);
    dlclose(handle); // 關(guān)閉句柄
    return 0;
}

使用 vscode 遠(yuǎn)程調(diào)試,哈哈,得到了我們想要的結(jié)果,截圖如下:

三:總結(jié)

這篇我們演示了 windows 上的 C# 調(diào)用 C# AOT 及 linux 上的 C 調(diào)用 C# AOT,是不是挺有意思,也算是給訓(xùn)練營學(xué)員提供的一份資料參考。

轉(zhuǎn)自https://www.cnblogs.com/huangxincheng/p/18900163


該文章在 2025/6/9 9:22:31 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved