VC 静态库与动态库(四)动态库创建与使用_显示调用
在第三章的基础上,接着添加一个显示调用项目
显示调用项目创建:
1.给解决方案添加一个新的控制台项目DisplayCall用于测试动态库,创建完成后设置为启动项目

2.DisplayCall.cpp添加相关代码 1 // DisplayCall.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <windows.h> //需要包含windows.h typedef int(*PFUNC_MathSub)(int,int); //定义函数指针 int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hmdll = ::LoadLibrary(_T("../Debug/DynamicLibrary.dll"));//动态加载dll
if(!hmdll)
{
printf("LoadDll is fail");
}else
{
//获取动态库中的sub函数地址,强制类型转换为函数指针
PFUNC_MathSub pfMathSub = (PFUNC_MathSub)::GetProcAddress(hmdll,"MathSub");
int nResult = pfMathSub(,); //通过函数指针进行调用
printf("5 - 3 = %d",nResult);
21 ::FreeLibrary(hmdll);
}
getchar();
return ;
}
3.编译运行DisplayCall,结果发现出现异常?

4. 点击中断发现断在第19行,鼠标移到pfMathSub发现它的值为0. 说明没有获取到MathSub函数地址
打开动态库的头文件进行查看是不是输错函数名字了?函数名正确...

5. 真正导致bug产生的原因在于,C++函数编译时产生的函数名称与代码中实际函数名是不一样的
这里动态库项目采用的是c++, 那它生成时就是按C++编译方式生成函数名
这里可以使用depends来查看下dll信息,可是vs2012工具里尽然没有,那就只能借用第三方工具了

原始c++函数:int MathSub(int a ,int b) 编译后函数名称:?MathSub@@YAHHH@Z
c++函数名称都是以?开头,后面跟上函数名,然后@@YA代表的是c++默认调用方式__cdecl,
后面二个H代表是参数型是int型,返回值是int型,最后以@z代表结尾
6. 为了测试是否正确,修改代码, 把GetProcAddress第二个参数函数名改为?MathSub@@YAHHH@Z
F5运行,发现能成功调用MathSub函数了

7. 如果每次调用动态库中的函数都使用这种方式太过于复杂,于是忽另外一种简单的方式应运而生
修改动态库头文件,在函数最前面加上extern "C", 告诉编译器不要使用默认的C++方式编译,
该为使用C语言方式编译. 最后重新编译下动态库工程

8. 回到DisplayCall.cpp中,把代码改回来. 然后F5运行,发现异常信息消失了

9. 最后再用工具看一下用extern "C" 修饰的函数编译出来的函数名变成什么样了?
C语言方式编译出来函数名是MathSub, 这样我们就可以很方便的使用GetProcAddress获取函数地址了

总结:
如果需要显示调用动态库,尽量在导出函数前面加上extern "C"
而当使用第三方动态库,去GetProcAddress函数地址发现获取不到函数地址时,
可以尝试用工具去查看导出函数,以确定函数名称,以及查看相关的调用约定
VC 静态库与动态库(四)动态库创建与使用_显示调用的更多相关文章
- VC 静态库与动态库(三)动态库创建与使用_隐式链接
动态库分为二种,一种隐式链接,另一种显示调用.不论哪种动态库,本质都是运行时动态加载 隐式链接:程序运行时,由编译系统自动加载动态库,然后根据程序的引入表进行重定位,当程序退出时自动卸载动态库 显示调 ...
- 1.改变项目 动态库、静态库属性。 2.使用运行库 /MD、/MT、/LD说明
/MD./MT./LD(使用运行库) 有关 C 运行库以及使用 /clr(公共语言运行时编译) 进行编译时要使用哪些库的更多信息,请参见 CRT 库功能. 传递给链接器的给定调用的所有模块都必须使用相 ...
- mingw qt(可以去掉mingwm10.dll、libgcc_s_dw2-1.dll、libstdc++-6.dll的依赖,mingw默认都是动态链接gcc的库而TDM是静态链接gcc库,tdm版本更好用。用aspack压缩没有问题。qt本身不使用异常处理)good
原文地址:mingw qt作者:孙1东 不使用Qt SDK,使用mingw编译qt源代码所遇问题及解决方法: configure -fast -release -no-exceptions -no-r ...
- GifShot - 创建动态 GIF 的 JavaScript 库
GifShot 是一个可以创建流媒体,视频或图像的 GIF 动画的 JavaScript 库.该库的客户端特性使其非常便携,易于集成到几乎任何网站.利用最先进的浏览器 API ,包括 WebRTC , ...
- 再探Linux动态链接 -- 关于动态库的基础知识
在近一段时间里,由于多次参与相关专业软件Linux运行环境建设,深感有必要将这些知识理一理,供往后参考. 编译时和运行时 纵观程序编译整个过程,细分可分为编译(Compiling,指的是语言到平台 ...
- PHP 动态添加 Mcrypt 扩展库
简介: PHP 动态添加 Mcrypt 扩展库,这是一个支持多种加密.解密算法.模式的扩展库. shell > php -m | grep mcrypt # 如果没有输出,就是缺少这个扩展 sh ...
- 再探Linux动态链接 -- 关于动态库的基础知识(Dynamic Linking on Linux Revisited)
在近一段时间里,由于多次参与相关专业软件Linux运行环境建设,深感有必要将这些知识理一理,供往后参考. 编译时和运行时 纵观程序编译整个过程,细分可分为编译(Compiling,指的是语言到平台 ...
- GCC链接库的一个坑:动态库存在却提示未定义动态库的函数
背景 在GCC中已经指定链接库,然而编译时却提示动态库函数未定义! 测试出现的错误提示如下: [GMPY@13:48 tmp]$gcc -o test -L. -lmylib test.c /tmp/ ...
- 动态代理的两种方式,以及区别(静态代理、JDK与CGLIB动态代理、AOP+IoC)
Spring学习总结(二)——静态代理.JDK与CGLIB动态代理.AOP+IoC 目录 一.为什么需要代理模式 二.静态代理 三.动态代理,使用JDK内置的Proxy实现 四.动态代理,使用cg ...
随机推荐
- UTC和GMT什么关系?moment处理世界时问题
UTC和GMT什么关系? 个人理解,两者基本一样,要说区别,那就是UTC更准确,而GMT误差有点.由于历史原因,以前用GMT,后来发现有些误差,改用UTC 我们可以看到,JS的 Date() 用的是G ...
- .NET CORE下最快比较两个文件内容是否相同的方法
本文因为未考虑磁盘缓存, 结果不是很准确, 更严谨的结果请参看本博文的续集 最近项目有个需求,需要比较两个任意大小文件的内容是否相同,要求如下: 项目是.NET CORE,所以使用C#进行编写比较方法 ...
- linux下如何查看自己都装了什么服务
service --status-all 先把rabbitmq进程杀掉 ps -ef | grep rabbitmq | grep -v grep | awk '{print $2}' | xargs ...
- Python Dataframe 分组排序和 Modin
Python Dataframe 分组排序和 Modin 1.按照其中一列进行排序 在dataframe中,按照其中的一列排序:比如q值倒排 (1)rank方法 data['new_rank'] = ...
- 关于Pragma
/** This is a introduction of how to use pragma. */ #pragma once /// This is used for include the he ...
- 尽解powershell的workflow
尽解powershell的workflow -------1[简介]--------- Microsoft .NET Framework 4.0 发布于2010年4月左右..net4 的新特性,是并行 ...
- Vue router-link路由不同的写法,不一样的效果
我想要的路径:http://localhost:8080/#/main/hato/realtime/eventDetail/238 情况一:未进行路由配置: { path: 'eventD ...
- 『公交线路 状压dp 矩阵乘法加速』
公交线路 Description 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的 ...
- QT+OpenGL(04)—freetype库的编译
1.freetype库的下载 https://www.freetype.org/download.html freetype-2.10.0.tar.bz2 2.解压 3.进入 freetype-2. ...
- NET 特性(Attribute)
NET 特性(Attribute) 转自 博客园(Fish) 特性(Attribute):是用于在运行时传递程序中各种元素(比如类.方法.结构.枚举.组件等)的行为信息的声明性标签. 您可以通过使用特 ...