首页 > 其他分享 >.NET Native AOT的静态库与动态库

.NET Native AOT的静态库与动态库

时间:2023-07-15 22:34:11浏览次数:33  
标签:调用 函数 int 导出 AOT AddFunc NET Native

.NET不仅可以使用 C静态库与动态库,也可以将.NET实现的函数导出为C静态库与动态库。在没有Native Aot之前,.NET只能通过P/Invoke享受C/C++生态,而在Native Aot之后,不仅可以享受这些生态,还可以开发SDK供其他语言调用。

.NET Native AOT的NativeLib参数用于指定本机库的类型。在.NET 7中,该参数有两个选项:Static和Shared。

  • Static: 生成静态库,意味着所有依赖项都将被编译到生成的可执行文件中,因此它更适合独立应用程序或需要最小化依赖项的应用程序。
  • Shared: 生成动态库,意味着依赖项将被编译为单独的本机库,并在运行时动态加载。这种方法可以减少生成文件大小,并且更适合需要共享依赖项的应用程序,所以它也被称为共享库。

使用UnmanagedCallersOnly特性可以将C#函数导出提供给C调用,EntryPoint属性用于指定导出的方法名称。

.NET函数导出

使用UnmanagedCallersOnly特性可以将C#函数导出提供给C调用,EntryPoint属性用于指定导出的方法名称。

public static class MyFunctions
{
    [UnmanagedCallersOnly(EntryPoint = "Add")]
    public static int Add(int a, int b)
    {
        return a + b;
    }

    [UnmanagedCallersOnly(EntryPoint = "PrintString")]
    public static void PrintString(IntPtr str)
    {
        Console.WriteLine(Marshal.PtrToStringAnsi(str));
    }

    [UnmanagedCallersOnly(EntryPoint = "GetSystemInfoWrite")]
    public static void GetSystemInfo()
    {
        Console.WriteLine($"ProcessorCount: {Environment.ProcessorCount}");
        Console.WriteLine($"MachineName: {Environment.MachineName}");
    }

}

在项目属性中加入PublishAot即可:

<PropertyGroup>
 <PublishAot>true</PublishAot>
</PropertyGroup>

您可以使用以下命令来指定NativeLib参数:

dotnet publish -r win-x64 -c release /p:NativeLib=Static

dotnet publish -r win-x64 -c release /p:NativeLib=Shared

通过JetBrains dotPeek工具查看DLL文件中是否包含导出的几个函数:

在C++中使用Native dll

在C++中调用DLL函数也可以分为隐式调用和显式调用两种方式。

隐式调用

附加库目录---添加文件引用的lib动态库路径:

项目->属性->配置属性->链接器->常规->附加库目录:加上lib文件的存放目录;

附加依赖项---添加工程引用的lib文件名:

项目->属性->配置属性->链接器->输入->附加依赖项:加上lib文件名。

隐式调用是指在代码中直接使用函数名进行调用,而编译器会自动根据参数类型匹配合适的函数。

例如:

#include <iostream>
extern "C"
{
	typedef int(AddFunc)(int, int);
	typedef void(PrintStringFunc)(const char*);
	typedef void(GetSystemInfoWriteFunc)();

	__declspec(dllimport) AddFunc Add;
	__declspec(dllimport) PrintStringFunc PrintString;
	__declspec(dllimport) GetSystemInfoWriteFunc GetSystemInfoWrite;
}

int main()
{
	int result = Add(1, 2);
	std::cout << "Result: " << result << std::endl;
	PrintString("Hello, world!");
	GetSystemInfoWrite();
	return 0;
}

随后编译项目,运行C++应用程序即可,如下所示。

Result: 3
Hello, world!
ProcessorCount: 12
MachineName: DESKTOP-MJL9J4R

显式调用

显式调用是指在代码中通过函数指针或者GetProcAddress等API来获取DLL中导出函数的地址,并通过该地址来进行调用。

  • 加载 DLL 文件并返回句柄:HMODULE hDll = LoadLibraryA(PathToLibrary);
  • 获取 DLL 中导出函数地址并赋值给指针变量:AddFunc pAdd = (AddFunc)GetProcAddress(hDll, "Add");
  • 显式地通过指针变量来调用从 DLL 中导出的 add 函数:int c = pAdd(a,b);

例如:

#include <windows.h>
#define PathToLibrary "C:\\Users\\hueifeng\\OneDrive\\InteropSample\\dotnetSample\\bin\\Release\\net7.0\\win-x64\\native\\dotnetSample.dll"

typedef int (*AddFunc)(int, int); // 定义一个函数指针类型

int main()
{
	HMODULE hDll = LoadLibraryA(PathToLibrary); // 加载dotnetSample.dll文件并返回句柄
	AddFunc pAdd = (AddFunc)GetProcAddress(hDll, "Add"); // 获取Add函数的地址并赋值给pAdd

	int a = 1, b = 2;
	int c = pAdd(a, b); // 显式地通过pAdd指针来调用从DLL中导出的add函数
}

标签:调用,函数,int,导出,AOT,AddFunc,NET,Native
From: https://www.cnblogs.com/yyfh/p/17557101.html

相关文章

  • kubernetes之 RBAC
    第十一部分RBACrestful操作对象:许可授权都作用于角色,用户是什么角色,就拥有什么操作权限授权插件:Node、ABAC、RBAC、WebhookRBAC:Role-basedAC角色:Role许可:permission关联图示客户端访问示意图:role:operations:许可object:rolebinging:useraccountorserviceacco......
  • React/Redux/React-Native 代码片段
    ES7+React/Redux/React-Native代码片段ES7+React/Redux/React-Nativesnippets一个使用react开发的代码片段插件。Snippetsinfo前置知识:代码片段中每个花括号{}和圆括号()内部的空格意味着将其推到下一行......
  • dotnet 连接sqlite数据库 orm EntityFrameworkCore
    dotnet_learn/appsettings.json{"Logging":{"LogLevel":{"Default":"Information","Microsoft.AspNetCore":"Warning"}},"AllowedHosts":"*"}d......
  • .NET个人博客-使用Back进行消息推送
    使用Back推送消息到你的iPhone前言我的好友看了我的博客,给我提了个需求,让我搞个网站通知,我开始以为就是评论回复然后发送邮件通知。不过他告诉我网站通知是,当有人评论或者留言后,会通知到我这边来,消息是实时通知的,他说用的是Back,不需要发邮件,然后发了个GitHub链接给我,我觉得还不......
  • .Net FrameWork下面如何生成AOT呢?
    前言其实AOT预编译,在.NetFrameWorker1.0里面就有了。它叫做Ngen,只不过当时叫做生成本机映像,实际上还是一个东西,也就是预编译。本篇来看下。原文:.NetFramework生成AOT概括1.介绍现在的现代化的.Net已经到了.Net8了,它的AOT程序已经趋近于完美。可以单个Exe运行在MacOS/Linux/W......
  • 将gephi文件导入到networkx中使用
    最近基于Transbigdata库编写代码获取了某市轨道交通网络的邻接表及shp文件,并使用Gephi对轨道交通网络进行了可视化处理,之后想尝试一下把Gephi的成果快捷地转为networkx格式来计算各种指标,编写了一些代码,步骤如下:1.将gephi成果导出打开gephi文件后点击文件—输出—图表文件选择......
  • 推荐一款.NET开源的轻量级分布式服务框架
    前言今天要给大家推荐一款由新生命开发团队开源的.NET轻量级分布式服务框架:星尘分布式平台(NewLife.Stardust)。项目介绍星尘是一个轻量级分布式服务框架。它的功能包含配置中心、集群管理、远程自动发布、服务治理、服务自动注册和发现、负载均衡、动态伸缩、故障转移、性能监控......
  • kubernetes之 认证和serviceaccount
    第十部分认证和serviceaccount前面讲的都是admin超级用户在操作k8s,Kubectl不能所有人都可以使用和访问。用户访问逻辑图,认证:第一种令牌认证token,最简单的认证,(只需要对方认证的共享密钥即可)服务器需要认可客户端的证书。授权:RBAC,基于角色的访问控制,目前用的比较多。    ......
  • 基于ASP.NET学生故障管理系统
    系统功能模块设计1.系统登录:系统登录是用户访问系统的路口,设计了系统登录界面,包括用户名、密码和验证码,然后对登录进来的用户判断身份信息,判断是管理员用户还是普通用户。2.系统用户管理:不管是超级管理员还是普通管理员都需要管理系统用户,包括普通管理员的添加、删除、修改、查询,修改......
  • kubernetes之 statefulset控制器
    第九部分statefulset控制器参考:https://blog.csdn.net/styshoo/article/details/73731993     https://blog.51cto.com/xuexinhuan/5424144即便是有状态管理,也需要使用脚本来运维。CoreOS:OperatorStatusfulSet:有状态Cattle,petPetSet->StatefulSeta、稳定......