c++动态库加载顺序和同名动态库同时加载问题

C++静态库与动态库:原理、创建、使用与工程实践指南 在软件工程中,库是代码复用和模块化设计的核心概念,它将通用功能封装为可复用的二进制组件。从原理上看,库分为静态库和动态库两种主要形式,其根本差异在于链接时机和代码合并方式。静态库在编译链接期将代码直接复制到最终可执行文件中,生成独立、自包含的程序,但会导致磁盘空间浪费和更新困难;动态库则在运行时被加载和映射到进程内存空间,支持多进程共享同一份代码,显著节省内存并便于模块化更新,但带来了依赖管理和版本兼容性等挑战。这两种技术方案在性能、部署、维护等方面各有优劣,其选择直接影响程序的体积、启动速度、内存占用和部 阅读详情

 本文仅 供学习参考,欢迎提出 宝贵意见

一,同名称动态库加载顺序。  

现有同名称动态库Dllpath.dll 3个,内容非常简单,分别为

extern "C" __declspec(dllexport) void myPrint()
{
OutputDebugStringA("exe path\n");
}


extern "C" __declspec(dllexport) void myPrint()
{
OutputDebugStringA("sys path\n");
}


extern "C" __declspec(dllexport) void myPrint()
{
OutputDebugStringA("SetDllDirectoryA path\n");
}

将这3个dll分别放入exe path(Debug)下,系统目录(我选的是C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin)下,exe path下的新建的目录path下,来检测这3个dll谁会先加载。

main测试代码如下:

void test3()
{
	SetDllDirectoryA("D:\\work\\vs2010_project\\DllPathTest\\Debug\\path"); 
	HINSTANCE dllinstance2 = ::LoadLibrary(L"Dllpath.dll");
	if (dllinstance2)
	{
		typedef void (*PathPrint)();
		PathPrint pp = (PathPrint)GetProcAddress(dllinstance2, "myPrint");
		pp();
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	test3();
	getchar();
	return 0;
}

测试结果为:

打印出exe path。   如果删除exe pah下的该dll,那么打印出SetDllDirectoryA path。 如果再删除Debug\paht下的dll,那么才打印出sys path。

那么由结果可以得出,加载顺序优先级为:exe path > SetDllDirectory path > sys path


2,同名动态库同时加载问题。

在工作中有时候会碰到这样的问题,我一个工程项目需要同时引用多个第三方库(不同厂商SDK),先比如我有工程Demo,要引用两个厂家的sdk,厂家1的sdk内容为

(a.dll, b.dll , c.dll), 厂家2的sdk内容为(a.dll , d.dll, e.dll),注意,这里的两个a.dll 是不一样的,只是名字相同。那么怎么同时加载这两个厂家的sdk呢?

第一种尝试:同时放在exe path下,当然显然不行,覆盖了嘛。

第二种尝试:分别建两个目录,然后把两个厂家的sdk,分别放入两个目录下,然后动态加载(Loadlibrary),当然这里如果两个厂家的sdk太过复杂的话,可以将它们做一次封装。结果为:如果先加载厂家1的sdk,那么再加载厂家2的sdk的时候,加载厂家2的a.dll时候,(Loadlibrary)的返回值为加载厂家1的a.dll相同地址,也就是说,加载厂家2的a.dll是无效的,其实返回的是厂家1的a.dll,那么由此可以得出程序在加载dll的时候,如果加载 到有已经加载过的dll(名字相同),那么就不会重新加载,而是返回之前加载过的dll,(个人猜测,程序是有个dll加载列表的)。

第三种尝试:和第二种尝试几乎 一样,不同之处在于加载两个厂家sdk的时候,不使用动态加载,而是对两个厂家的sdk进行封装(成factory1.dll,  factory2.dll),这两个dll都是使用静态加载的方法去加载各自的 sdk,但是结果和第二种尝试是一样的。

第四种尝试:将两个厂家的sdk封装成com组件,测试结果同样为,先加载的组件有效,后加载的com组件无效。

第五中尝试:根据之前的 尝试,猜测程序是有dll加载列表的,所以只要我有同名的dll,无论怎么加载,后加载的dll都不会成功(返回先加载的dll)(如果有好的方法,请留言,非常感谢)。于是,只能采用进程间通信,(就是开进程加载各自的sdk)这样能解决(但是相对麻烦些了)。


以上为本人的一些测试结果,欢迎提出 不同意见

Linux动态库symbol lookup error:五大原因与系统化排查实战 动态链接是现代软件模块化设计的核心技术,它允许程序在运行时加载共享库,实现代码复用和解耦。其核心原理是运行时链接器(ld-linux.so)根据全局符号表,为程序中的未定义符号查找并绑定到动态库中的定义。这项技术的价值在于提升开发效率、减少内存占用并支持插件化架构,广泛应用于操作系统核心服务、数据库中间件及大型应用程序中。然而,在涉及多个动态库相互调用的复杂系统中,常因**符号可见性**或**ABI兼容性**等问题,引发运行时链接错误。本文聚焦于典型的`symbol lookup error`,深入剖析其五 阅读详情

相关推荐

萤石云C++ SDK接入实践:动态库封装、回调桥接与加载失败排查

在C++工程中引入第三方动态库是常见的集成方式,但动态库的依赖管理、头文件组织与运行期加载问题往往比预想中复杂。理解动态库的加载机制与符号解析原理,是保障程序稳定运行的基础。通过合理的封装层设计、回调线程模型梳理与生命周期管理,可以显著降低集成风险。在实际应用中,视频服务、设备接入等场景常面临库缺失、版本冲突与回调异常等问题。本文以萤石云C++ SDK接入为例,梳理从CMake工程配置、动态库加载到调用封装与问题排查的完整链路,为C++桌面端与服务端集成提供可参考的实践路径。

weixin_30983353的博客 178

链接两个“名字完全一样”的【动态库】,你会怎么处理?

作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++、嵌入式、Linux。 目录 文章目录第一个动态库文件应用程序第二个动态库文件错误做法:直接给它改名正解:patchelf 工具One More Thing 在Linux应用的开发过程中,直接利用现成的第三方库(俗称:轮子)来完成自己的业务功能,是很常见的事情。 不知道你是否遇到这样的场景:应用程序中需要使用两个动态库里的不同功能的函数,但是这两个动态库的作者发生心灵感应了,居然起了完全一样的动态库名字,这该如何是好? 具体来说面对的问题是..

IOT物联网小镇 1988

求助:有没有基于pscad的锂电池仿真模型

求助:有没有基于pscad的锂电池仿真模型 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变没有 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写...

qq_38922523的博客 1222

多个c/c++动态库函数同名冲突解决方法

最近某个程序需要调用多个动态库,但是不同的动态库中使用了功能不同的同名函数,导致调用出现偏差,可参考以下解决办法。 样例 假设有动态库libFuncA.so和libFuncB.so,他们的内部实现分别为: /*func_A.c*/ #include<stdio.h> //内部函数 int sayHi() { printf("Hi,this is AAAAA\n"); return 0; } //外部调用函数 int sayOut() { sayHi();

woniuye的博客 7705

STM32F407 HAL库 LIN DMA 配置实战与汽车电子应用解析

本文详细解析了STM32F407 HAL库在LIN总线通信中的DMA配置实战,重点介绍了硬件自动处理断点检测、同步场和校验和的优势。通过具体代码示例和汽车电子应用案例(如车窗控制、座椅调节),阐述了如何利用DMA提升通信效率与稳定性,为成本敏感的汽车电子系统提供高效解决方案。

study的专栏 968

android mtk camera如何自定义默认拍照与录像分辨率

本文详细解析了在Android MTK平台上自定义相机默认拍照与录像分辨率的方法。通过分析Camera2应用默认选择逻辑,定位并修改PictureSize.java与VideoQualityCaptureRequestConfig.java中的关键代码,实现绕过系统智能选择,强制指定最高或特定分辨率。文章还提供了进阶的可配置化方案与验证避坑指南,帮助开发者精准控制相机行为。

weixin_29194817的博客 432

dll的加载顺序

总结:dll的加载顺序: (1)EXE所在目录; (2)当前目录GetCurrentDirectory(); (3)系统目录GetSystemDirectory(); (4)WINDOWS目录GetWindowsDirectory(); (5)环境变量 PATH 所包含的目录。 所以使用loadlibrary加载dll使用的路径,但是这个函数会忽略这个路径,只会按既定规则加载dll。所以如果要...

qq_41786318的博客 3064

移远EC800M CAT1模块HTTP POST实战:从AT指令到OneNet平台数据上报(附STM32代码)

本文详细介绍了移远EC800M CAT1模块通过AT指令实现HTTP POST数据上报到OneNet平台的完整流程,包含STM32实战代码。内容涵盖PDP上下文激活、HTTP服务配置、JSON数据包构建等关键技术要点,并提供硬件连接、状态机设计和错误处理等实用方案,助力开发者快速实现物联网设备稳定数据传输。

weixin_42565652的博客 507

C语言 调用的动态库函数重名问题分析

设计两个动态库 第一个动态库:libHelloc: func1.h #ifndef FUNC1_H_ #define FUNC1_H_ int func1(); void func(); #endif func1.c #include "func1.h" int func1() { return 0; } void func() { printf("func at

hknaruto的专栏 7653

飞书日历同步Outlook翻车?我踩过的坑和最终用Google Calendar成功的完整配置记录

本文详细记录了从Outlook日历同步到飞书时遇到的常见问题及解决方案,特别是通过Google Calendar实现稳定同步的完整配置流程。文章揭示了Outlook同步方案易翻车的原因,并提供了Google Calendar的避坑指南、高级技巧和企业级部署建议,帮助用户高效实现日历同步。

weixin_33724046的博客 313

Spring Boot 微服务 API 网关实战:Spring Cloud Gateway 整合,搞定路由转发 + 统一认证 + 限流熔断(企业级落地)

摘要:本文详细介绍了SpringCloud Gateway在微服务架构中的核心作用与实现方案。作为API网关,它解决了服务入口分散、认证冗余、流量失控等痛点,提供路由转发、统一认证、限流熔断等能力。文章通过图书管理系统案例,演示了SpringBoot整合Gateway的全流程,包括基础路由配置、JWT全局认证、局部参数校验、Sentinel限流熔断以及Nacos动态路由等核心功能实现。特别强调了企业级落地中的关键注意事项,如路由顺序、过滤器执行顺序、HTTPS配置等。该方案能有效构建统一、安全、高效的微服务

lamehsl的专栏 1381

Windows DLL 的搜索顺序

Dynamic-Link Library Redirection 通常情况下,应用程序加载DLL时的搜索路径顺序如下: The directory from which the application loaded. The system directory. The 16-bit system directory. The Windows directory. The curre...

humadivinity的博客 1173

蓝桥杯第七届省赛试题--“模拟风扇控制系统”

题目要求 功能简述 “模拟风扇控制系统”能够模拟电风扇工作,通过按键控制风扇的转动速度和定时时间,数码管实时显示风扇的工作模式,动态倒计时显示剩余的定时时间,系统主要由数码管显示、单片机最小系统、按键输入和电机控制保护电路组成,系统框图如图 1 所示: 单总线驱动程序、CT107D 单片机考试平台电路原理图以及本题所涉及到的芯片数据手册,可参考计算机上的电子文档。程序流程图及相关工程文件请以考生...

qq_43280087的博客 2659

C/C++多个链接库含有同名函数,编译会报错吗

C/C++多个链接库含有同名函数,编译会报错吗起因基本概念同名函数测试测试1:`.o`目标文件测试2:静态库测试3:动态库同名函数的应用 起因 由于业务需要,我司使用了Mellanox某闭源C++程序,Mellanox推荐的定制化开发方法是:对其链接的动态库进行定制化开发,以添加额外的功能。 在方案讨论阶段,发现很多同事对动态库/静态库所代表的的含义并不十分清楚,特别是当同名函数存在时,编译、链接、运行的结果是什么也没有明确的认识,故写下这篇文章。 基本概念 程序函数库可分为下面几种类型: 静态函数库(

杰特JET的博客 6201

AD9914数字斜坡模式使用

类似的,如果DRG输出处于负斜率斜坡中间,DRCTL引脚由逻辑0变为逻辑1,那么DRG会立即切换成正斜率参数,恢复在两个限值之间振荡输出。当两个非驻留位同时设置时,每次DRG输出达到编程设定的上限值或下限值后(假定DRG过输出使能位(0x01[13])已设置),DROVER信号会产生一个正脉冲(两个DDS时钟周期)。不过,在非驻留操作中,DRG输出不一定保持在上下限值。例如,设置数字斜坡非驻留高位,则当达到上限值时,DRG会自动(立即)跳到下限值(这一过程并非以斜坡方式返回下限值,而是直接跳至下限值)。

wangjie36的博客 3864

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

记录一次采坑--如何处理Linux动态库同名函数?

一、背景介绍 需求描述:业务提供一个鉴权的静态库,我只需要从url 和 参数中提取相应的参数传给业务的静态库,将静态库的处理结果直接返回给业务(return < 0, 直接返回403)。 但是最近业务反馈,请求部分url直接返回Error:-1015错误,不符合预期。 二、分析过程 业务刚开始反馈问题,我的第一反应:怎么可能是我的问题,我就仅仅写了一个so(暂时命名1.so),直接调用了你...

lotluck的专栏 2176

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C/C++语言动态库下的坑

这个问题确实是动态库开发中的一个常见陷阱,尤其是在大型项目中,多个库之间可能会有符号冲突。了解符号解析的规则和采取适当的措施可以帮助避免这些问题。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 668

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

c/c++依赖静态库、动态库符号问题

一些结论: liba.so / liba.a对应cpp int subfunc(int a, int b) { return a + b; } int funcA(int a, int b) { return subfunc(a, b); } 符号信息 liba.so: func_sub, func_a libB.so / ...

lgfun的专栏 4010

一次使用LD_DEBUG定位问题的经历

在实际工作中,当遇到段错误,我们会很容易的想到这是非法访问了内存导致的,比如访问了已经释放的内存,访问数据越界,尝试写没有写权限的内存等。使用gdb进行调试,查看出异常的调用栈,往往可以定位到问题原因。但是有些时候,段错误问题的定位也没这么简单。本人在工作中就遇到了一个段错误的问题,问题原因不是那么直观,出问题的代码非常简单,直接按照常规的分析方法,很难分析出原因。往内存越界、内存没有权限这个方向分析无法定位问题。可执行文件直接依赖两个动态库,两个动态库有同名符号,这样编译可执行文件的时候无法编译通过。

weixin_38184628的博客 1647

全网首发:由两个库同名函数,看LINUX动态库加载及调用

  最近的字体问题,有点怪: 系统库叫freetype,吾库叫tsfreetype。 执行程序先freetype,随后在使用时加载tsfreetype。功能出错。 使执行程序强制依赖tsfreetype,功能正常。   为什么出错?因为两个库有同名函数。具体来说相当于: freetype库,B函数,调用C。 tsfreetype库,D函数,调用C。   D函数调用C,并不一定调用的是自己库里的,而是看哪个库加载,就先调用哪个。也就是说,LINUX动态库的原则是先入为主。   这个问题怎么解决呢?

柳鲲鹏 1213

Linux——C/C++静态库与动态库完全指南:从制作到实战应用

本文全面介绍了C/C++中静态库和动态库的制作与使用。静态库通过ar工具将.o文件打包为.a文件,编译时嵌入可执行程序;动态库使用-fPIC和-shared生成位置无关的.so文件,运行时加载。文章详细对比了两者在链接时机、内存占用、升级维护等方面的差异,并提供了四种动态库配置方案。还涵盖混合链接优先级、Windows平台差异处理等实用技巧,以及CMake构建示例。开发者可根据项目需求选择合适库类型,提升代码复用性和维护性。

wz_290793的博客 1328

linux动态库相对严谨的做法

当一个项目规模扩大到一定程度,动态库间的冲突容易成为项目的噩梦。 问题在于linux下生成的动态库,默认会导出所有非静态函数、全局变量及静态变量,容易出现不同库中出现同名函数及变量, 而linux下在处理这种同名函数时,仅仅是留下最先加载的函数版本,容易造成莫名奇妙的问题。 windows下的动态库就不容易出现这个问题了,因为只有显式标记的函数和变量才会被导出。 linux下的动态库要达到

tanggula的专栏 732

程序的链接和加载基础(2)

1.7 符号查找路径   通常在.h文件中声明函数,在.c/.cc文件(静态库/动态库)中定义函数。上面的演示中,在需要函数声明的地方,都是手工声明的。   头文件的查找路径,如果#include "header",那么header在当前路径查找,如果#include ,那么header在/usr/include 和 /usr/local/include 路径查找。

zqt520的专栏 808

Hook技术

linux上基于C和C++的hook尝试

jinking01的专栏 4418

动态加载DLL实现不同DLL的相同导出函数调用问题

假设这样的情景:         一个exe加载了两个dll(dll1和dll2,并使用隐式加载)。dll和dll2都同时向外导出一个函数:         int add(int a, int b);         如果在exe中调用了add函数,那么它调用的会是哪个dll的add函数呢?         为了验证这个结果,写了一个测试的例子。两个dll(win32的d

Nicole的成长 3705
上一篇: 安装ubuntu已将该虚拟机配置 为使用64位客户机操作系统错误
下一篇: android MediaCodec的自己碰到的问题
mincheat
博客等级 码龄17年 46粉丝 43原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值