C#跨平台P/Invoke时导入动态库的问题
众所周知C#的DllImport特性只允许将常量字符串赋值给DllName。
C/C++动态库在不同平台上可能具有不同的名称。
用nativedep这个库来举例:在windows上可能叫nativedep.dll、linux上叫libnativedep.so、macos上叫libnativedep.dylib。
幸运的是C#会处理常见的变体,如果使用nativedep作为DllName,以上变体都能正确匹配:
[DllImport("nativedep")]
static extern int ExportedFunction();
在 Windows 上运行时,将按以下顺序搜索 DLL:
nativedep
nativedep.dll(如果库名称尚未以 .dll 或 .exe 结尾)
在 Linux 或 macOS 上运行时,运行时将尝试在 lib 前添加,并追加规范共享库扩展。 在这些 OS 上,按以下顺序尝试库名称变体:
nativedep.so / nativedep.dylib
libnativedep.so / libnativedep.dylib 1
nativedep
libnativedep 1
在 Linux 上,如果库名称以 .so 结尾或包含 .so.(注意尾随 .),则搜索顺序会有所不同。 请考虑以下示例:
C#
[DllImport("nativedep.so.6")]
static extern int ExportedFunction();
在这种情况下,将按以下顺序尝试库名称变体:
nativedep.so.6
libnativedep.so.6 1
nativedep.so.6.so
libnativedep.so.6.so 1
仅当库名称不包含目录分隔符 (/) 时才检查路径。
但不幸的是有些库作者不按常理命名,导致默认的行为不管用,比如使用“libnativedep-0.dll”这种名称。这时可以考虑使用 NativeLibrary.SetDllImportResolver 来自定义解析规则。
如果你的库面向standard2.0、standard2.1,那么 NativeLibrary.SetDllImportResolver 是用不了的。一个可以考虑的做法是手动改掉c/c++动态库的名称使其匹配默认规则,前提是库内部不会依赖文件名称;
另一个做法是使用kernel32.LoadLibrary、libdl.dlopen封装一个中间层。可参考 https://github.com/mellinoe/nativelibraryloader。
相关资料:
SetDllImportResolver不支持.NET Standard
一个曾经踩坑的开源库,查看提交记录363a555d可以看到作者采用了两种方式
C#跨平台P/Invoke时导入动态库的问题的更多相关文章
- Linux下Gcc生成和使用静态库和动态库详解(转)
一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...
- Linux下Gcc生成和使用静态库和动态库详解
参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库 ...
- 【转】分析Linux和windows动态库
原文地址:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Lin ...
- [转]Linux下用gcc/g++生成静态库和动态库(Z)
Linux下用gcc/g++生成静态库和动态库(Z) 2012-07-24 16:45:10| 分类: linux | 标签:链接库 linux g++ gcc |举报|字号 订阅 ...
- Linux-Gcc生成和使用静态库和动态库详解
一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...
- linux静态与动态库创建及使用实例
一,gcc基础语法: 基本语法结构:(由以下四部分组成) gcc -o 可执行文件名 依赖文件集(*.c/*.o) 依赖库文件及其头文件集(由-I或-L与-l指明) gcc 依赖文件集(*.c/*.o ...
- Linux和windows动态库
转载:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 态链接库技术实现和设计程序常用的技术,在Windows和Linux系 统中 ...
- 修改OpenSSL默认编译出的动态库文件名称
在 Windows 平台上调用动态链接库 dll 文件时,有两种方式:a) 隐式的加载时链接:使用 *.lib (导入库)文件,在 IDE 的链接器相关设置中加入导入库 lib 文件的名称,或在程序中 ...
- 【转】Linux下gcc生成和使用静态库和动态库详解
一.基本概念 1.1 什么是库 在Windows平台和Linux平台下都大量存在着库. 本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不 ...
- linux动态库与静态库混合连接
1, 在应用程序需要连接外部库的情况下,linux默认对库的连接是使用动态库,在找不到动态库的情况下再选择静态库.使用方式为: gcc test.cpp -L. -ltestlib 如果当前目录有 ...
随机推荐
- 使用 .NET Core 实现一个自定义日志记录器
目录 引言 1. 抽象包 1.1 定义日志记录接口 1.2 定义日志记录抽象类 1.3 表结构迁移 2. EntityFramework Core 的实现 2.1 数据库上下文 2.2 实现日志写入 ...
- 我的世界服务端插件安装 AuthMe用户登录插件安装
Minecraft服务端插件安装-AuthMe用户登录插件安装 需要准备AuthMe插件 AuthMe-5.6.0.jar用户登录插件 例如使用/register <密码> <确认密 ...
- @EnableWebMvc 注解会让Swagger无效访问的问题
在工作中,通过Swagger2对项目的controller进行配置,以便于用户测试restful服务接口提高开发效率. 但是今天却出现了一个让我匪夷所思的问题就是在配置类里面加上@EnableWebM ...
- Netty 那些事儿 ——— 关于 “Netty 发送大数据包时 触发写空闲超时” 的一些思考
作者:tomas家的小拨浪鼓链接:https://www.jianshu.com/p/8fe70d313d78来源:简书 本文是笔者和朋友(笔名:oojeek)一起讨论该问题的一个记录.文章以讨论过程 ...
- Qt/C++加载不同的地图控件/地图类型/缩放标尺/缩略图/比例尺/实时路况/全景视图等
一.前言说明 在展示地图的时候,有些常规的操作,比如调整地图的缩放级别,切换到卫星图等,希望能够在地图上直接操作实现,于是就有了一堆地图控件,可以根据自己的需求动态的添加和删除,这样就更直接更快捷,而 ...
- 阿里IM技术分享(五):闲鱼亿级IM消息系统的及时性优化实践
本文由阿里闲鱼技术团队有攸分享,原题"向消息延迟说bybye:闲鱼消息及时到达方案",有修订和改动,感谢作者的分享. 1.引言 IM消息作为闲鱼用户重要的交易咨询工具,核心目标有两 ...
- ConcurrentHashMap源码分析-JDK18
前言 ConcurrentHashMap是一个线程安全的HashMap,主要用于解决HashMap中并发问题. 在ConcurrentHashMap之前,也有线程安全的HashMap,比如HashTa ...
- Solution Set - “愿所有罗盘都指向那片海洋”
目录 0.「NOI Simu.」哈希计数 1.「NOI Simu.」运输计划 2.「NOI Simu.」时代的眼泪 3.「Subset」LP 的被动练习 4.「EC Final 2018」「LOJ # ...
- 开源的分布式事务解决方案-Seata
Seata 是什么? (1)Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务. (2)在 Seata 开源之前,Seata 对应的内部版本在阿里经济 ...
- nginx平台初探-3
过滤模块简介 (90%) 执行时间和内容 (90%) 过滤(filter)模块是过滤响应头和内容的模块,可以对回复的头和内容进行处理.它的处理时间在获取回复内容之后,向用户发送响应之前.它的处理过程分 ...