在第三章的基础上,接着添加一个显示调用项目

显示调用项目创建:

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 静态库与动态库(四)动态库创建与使用_显示调用的更多相关文章

  1. VC 静态库与动态库(三)动态库创建与使用_隐式链接

    动态库分为二种,一种隐式链接,另一种显示调用.不论哪种动态库,本质都是运行时动态加载 隐式链接:程序运行时,由编译系统自动加载动态库,然后根据程序的引入表进行重定位,当程序退出时自动卸载动态库 显示调 ...

  2. 1.改变项目 动态库、静态库属性。 2.使用运行库 /MD、/MT、/LD说明

    /MD./MT./LD(使用运行库) 有关 C 运行库以及使用 /clr(公共语言运行时编译) 进行编译时要使用哪些库的更多信息,请参见 CRT 库功能. 传递给链接器的给定调用的所有模块都必须使用相 ...

  3. 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 ...

  4. GifShot - 创建动态 GIF 的 JavaScript 库

    GifShot 是一个可以创建流媒体,视频或图像的 GIF 动画的 JavaScript 库.该库的客户端特性使其非常便携,易于集成到几乎任何网站.利用最先进的浏览器 API ,包括 WebRTC , ...

  5. 再探Linux动态链接 -- 关于动态库的基础知识

      在近一段时间里,由于多次参与相关专业软件Linux运行环境建设,深感有必要将这些知识理一理,供往后参考. 编译时和运行时 纵观程序编译整个过程,细分可分为编译(Compiling,指的是语言到平台 ...

  6. PHP 动态添加 Mcrypt 扩展库

    简介: PHP 动态添加 Mcrypt 扩展库,这是一个支持多种加密.解密算法.模式的扩展库. shell > php -m | grep mcrypt # 如果没有输出,就是缺少这个扩展 sh ...

  7. 再探Linux动态链接 -- 关于动态库的基础知识(Dynamic Linking on Linux Revisited)

      在近一段时间里,由于多次参与相关专业软件Linux运行环境建设,深感有必要将这些知识理一理,供往后参考. 编译时和运行时 纵观程序编译整个过程,细分可分为编译(Compiling,指的是语言到平台 ...

  8. GCC链接库的一个坑:动态库存在却提示未定义动态库的函数

    背景 在GCC中已经指定链接库,然而编译时却提示动态库函数未定义! 测试出现的错误提示如下: [GMPY@13:48 tmp]$gcc -o test -L. -lmylib test.c /tmp/ ...

  9. 动态代理的两种方式,以及区别(静态代理、JDK与CGLIB动态代理、AOP+IoC)

    Spring学习总结(二)——静态代理.JDK与CGLIB动态代理.AOP+IoC   目录 一.为什么需要代理模式 二.静态代理 三.动态代理,使用JDK内置的Proxy实现 四.动态代理,使用cg ...

随机推荐

  1. tensorboard运行使用(排坑)记录一

    首先运行如下代码(路径根据你自己的要求更改) writer = tf.summary.FileWriter("G:/tensorflow/graph", tf.get_defaul ...

  2. remote: http basic: access denied fatal: authentication failed for '‘解决办法

    问题描述 由于这个项目代码使用https 进行clone,为什么?因为代码库ssh有问题!fuck! 导致在push代码的时候出现了 remote: http basic: access denied ...

  3. InvalidProgramException

    InvalidProgramException 这tmd是个什么错,我现在都想不起这个exception是怎么触发的了. 后来google了一下,发现是.net 2.0的编译器的bug,和内存或堆栈使 ...

  4. 安装Ubuntu时出现Intel VT-X没有开启

    试了很多种方法,最后原来是只需要进入bosi系统,然后进入Intel Virtual Technology 使之成为Enabled即可,就这么简单粗暴.

  5. Paper | Making a "Completely Blind" Image Quality Analyzer

    目录 1. 技术细节 1.1 NSS特征 1.2 选择锐利块来计算NSS 1.3 一张图像得到36个特征 1.4 用MVG建模这36个特征 1.5 NIQE指标 2. 实验 质量评估大佬AC Bovi ...

  6. Mac操作:Mac系统移动鼠标显示桌面(移动鼠标到角落)

    很多朋友都发现,有的人在用Mac的时候,鼠标一划就可以显示桌面,或者显示Launchpad.其实很简单,下面就介绍这个方法. 首先打开系统偏好设置: 然后点击红色圈中的图标:MissionContro ...

  7. go 1.13 环境变量配置

    GO111MODULE="off"GOARCH="amd64"GOBIN=""GOCACHE="/Users/js/Library ...

  8. linux bash 的基础语法

    示例均来自网络,附带有原始链接地址,自己练习整理发出,均测试可用 linux shell 基本语法 - 周学伟 - 博客园 https://www.cnblogs.com/zxouxuewei/p/6 ...

  9. Django学习笔记(11)——开发图书管理页面

    一,项目题目: 开发图书管理页面 该项目主要练习Django对多个数据库进行增删改查的操作. 二,项目需求: 基础需求:75% 1. 列出图书列表.出版社列表.作者列表 2. 点击作者,会列出其出版的 ...

  10. Netty中的ChannelFuture和ChannelPromise

    在Netty使用ChannelFuture和ChannelPromise进行异步操作的处理 这是官方给出的ChannelFutur描述 * | Completed successfully | * + ...