VC/MFC动态库Debug版本下正常,Release版本下错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC/MFC动态库Debug版本下正常,Release版本下错误相关的知识,希望对你有一定的参考价值。

在网上找了一个用MFC编写基于VLC类库的播放器的例子,也可以播放各种格式的视频,结果发现该例子有问题如下: 在Debug模式下,可以正常播放。 在Release模式下,仅编译就出现了18个链接的warning,一打开视频文件时就弹出应用程序错误。 int vlc_argc = 0; char *vlc_argv[100]; vlc_argv[vlc_argc++] = "--ignore-config"; p_instance[1] = libvlc_new(vlc_argc, vlc_argv, NULL); libvlc_media_t *p_media = libvlc_media_new(p_instance[1], m_VideoPath[1],NULL); p_media_player[1] = libvlc_media_player_new_from_media(p_media, NULL); libvlc_media_player_set_drawable(p_media_player[1], (libvlc_drawable_t)m_StaticDisplay[1]->m_hWnd, NULL); //各相应变量均在头文件中定义了,调用的函数声明位于:libvlc.h 中, 好像是从libvlc.dll的动态库中调用的 //具体原理都封装了起来,看不到所以我也不太清楚 其中链接警告如下: LINK : warning LNK4089: all references to "d000000.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000008.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000010.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000106.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000116.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000118.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000120.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000126.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000127.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000128.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000129.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000132.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000134.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000135.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000137.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000144.o" discarded by /OPT:REF LINK : warning LNK4089: all references to "d000164.o" discarded by /OPT:REF 注:我的.lib文件是添加在资源里的,Debug和Release的配置全是新建工程时的默认配置 以上的问题是怎么造成的,该怎么解决呢?望高手解答。。。急急急!

参考技术A 这些警告不会对你的程序运行的正确性产生影响,这只是提醒您有一些东西不需要,所以编译器在生成Release版本的时候就会做一些优化,所以会出现着一些警告,不用担心。
至于你提的问题,可能是您的程序自身设计的有问题。跟编译器没有关系。
估计就是打开的时候路径不对。或者文件没有给定。
估计在程序中别人使用了相对路径,这样才会导致Release版本运行错误。

VC++程序设计与应用--动态链接库

目录

前言

一、动态链接库

1.1 概述

1.1.1 动态链接库的概念

1.1.2 动态链接库和静态链接库的区别

1.1.3 使用动态链接库的优点

1.1.4 DLL文件的存放位置

1.2 创建MFC DLL

1.2.1 使用DEF文件

1.2.2 使用关键字_declspec(dllexport)

1.3 使用MFC DLL

1.3.1 使用隐式链接

1.3.2 使用显式链接

1.4 MFC拓展DLL

1.4.1 创建MFC扩展 DLL

总结


前言

本篇文章介绍动态链接库


一、动态链接库

1.1 概述

在多任务环境中,为了提高系统资源的利用率和系统的整体性能,应该使每一个应用程序尽量少占用系统内存等资源。

    动态链接库便是这一设想的体现,允许多个应用程序同时共享动态链接库在内存中的同一份拷贝。

1.1.1 动态链接库的概念

动态链接库(DLL):一种用来为其它可执行文件(包括EXE文件和其它DLL)提供共享的函数库。   

    DLL中一般定义有两种类型的函数:导出函数和内部函数。导出函数是可以被外部程序调用的函数,内部函数只能在DLL内部使用。

1.1.2 动态链接库和静态链接库的区别

动态链接库和静态链接库的主要区别是与应用程序的链接方式不同,前者进行的是动态链接,后者进行的是静态链接。

1.1.3 使用动态链接库的优点

(1) 实现多个应用程序共享数据和代码的方式。

(2) 提高应用程序的执行效率和运行速度。

(3) 方便应用程序的升级和售后支持。

(4)把应用程序所使用的资源,如图标、位图、字符串和对话框等,独立出来做成DLL,为多个应用程序所共享。

(5) 动态链接库便于建立多语言的应用程序。

1.1.4 DLL文件的存放位置

程序所需的DLL文件必须位于下面4个目录之一中:

(1) 当前目录

(2) Windows的系统的目录,如Windows\\system

(3) Windows所在的目录,如WINNT

(4) 环境变量PATH中所指定的目录

1.1.5 动态链接库的分类

Visual C++ 6.0支持多种DLL,包括:

  • MFC DLL

        一般来说,非MFC DLL的内部不使用MFC,非MFC DLL的导出函数都使用标准的C接口,因此无论应用程序是否使用了MFC,都可以调用非MFC DLL

  • MFC扩展DLL

    MFC扩展DLL一般用来提供派生于MFC的可重用的类,以扩展已有的MFC类库的功能。MFC扩展DLL使用MFC的动态链接版本。只有使用MFC生成的可执行程序(无论是EXE还是DLL)才能访问MFC扩展DLL

1.2 创建MFC DLL

利用MFC AppWizard[dll]向导可以创建MFC DLLDLL文件与可执行文件非常相似,不同点在于DLL包含有导出表。导出表包含DLL中每个导出函数的名字,这些函数是进入DLL的入口点。只有导出表中的函数可以被外部程序调用。

    从MFC DLL中导出函数常用以下两种方法:使用模块定义文件(.def)和使用关键字_declspec(dllexport)

1.2.1 使用DEF文件

DEF文件是一个包含EXE文件或DLL文件声明的文本文件。每个DEF文件至少必须包含LIBRARY语句和EXPORTS 语句,其他语句可以省略。

DEF文件常用的模块语句如下:

  1. 第一个语句必须是LIBRARY语句,这个语句指出DLL的名字,链接器将这个名字放到DLL导入库中,DLL导入库包含了指向外部DLL的函数索引指针。
  2. EXPORTS 语句列出被导出函数的名字, 以及导出函数的数值(由@号与数字构成)。序数值可以省略,编译器会为每个导出函数指定一个,但这样指定的值不如自己指定的明确。
  3. 使用DESCRIPTION语句描述DLL的用途,这个语句可以省略。
  4. 使用开头的注释语句。

1.2.2 使用关键字_declspec(dllexport)

MFC DLL中导出函数的另一种方法是在定义函数时使用关键字_declspec(dllexport)。这种情况下,不需要DEF文件。导出函数的形式为:

declspec(dllexport) <返回类型> <导出函数名>(<函数参数>)

1.2.3 两种导出函数方法的比较

  • 如果需要使用导出顺序值,那么应该使用DEF文件来导出函数。
  • 使用DEF文件来导出函数,可以创建具有NONAME属性的DLL
  • 使用declspec(dllexport)关键字导出函数不需要编写DEF文件,因此,如果编写的DLL只供自己使用,使用__declspec(dllexport)较为简单。

1.3 使用MFC DLL

应用程序与DLL链接后,DLL才能通过应用程序调用运行。应用程序与DLL链接的方式主要有如下两种:隐式链接和显式链接。

    隐式链接又称为静态加载,指的是使用DLL的应用程序先链接到编译DLL时生成的导入库LIB文件,执行应用程序的同时操作系统自动加载所需的DLL在应用程序退出之前,DLL一直存在于该程序运行进程的地址空间中。

    显式链接又称为动态加载,使用显式链接DLL的应用程序必须在代码中动态地加载所使用的DLL,并使用指针调用DLL中的导出函数,在使用完毕后,应用程序必须卸载所使用的DLL

1.3.1 使用隐式链接

使用隐式链接除了需要相应的DLL文件外,还必须具备以下2个文件:

  • 包含导出函数以及类声明的头文件
  • DLL的导入库LIB文件

 编译时将DLL的LIB文件加入应用程序中,主要有如下3种方法。

  1. 在主菜单project中,选择菜单项【Add To Project| Files】菜单项,在弹出的Insert Files Into Project对话框中选择所需的LIB文件。
  2. 在程序的StdAfx.h头文件中加入下列语句:#pragma comment (lib,"指定的LIB文件名")
  3. 在主菜单project中,选择【Settings】菜单项,弹出Project Settings对话框,如下图所示。选择Link选项卡,在Object/library modules文本框中输入指定的LIB文件名,多个库文件之间用空格分开。

1.3.2 使用显式链接

使用显式链接时,需要知道导出函数返回值的类型和所传递的参数个数、类型和顺序等。应用程序在调用DLL中的导出函数前,必须首先调用LoadLibrary()函数加载DLL并得到一个模块句柄,然后使用得到的模块句柄调用GetProcAddress()函数获取导出函数的指针,并使用该指针调用DLL中的导出函数。DLL使用完毕后,调用FreeLibrary()函数释放加载的DLL

    若DLLMFC扩展DLL,则应用程序应该分别使用AfxLoadLibrary()AfxFreeLibrary()函数来加载和释放DLL

1.4 MFC拓展DLL

MFC扩展DLL的含义在于它是MFC的扩展,其主要功能是实现从现有MFC类库中派生出可重用的类。

1.4.1 创建MFC扩展 DLL

    对于MFC扩展DLL,系统会自动在项目中添加如下表所示的宏,这些宏为DLL和应用程序的编写提供了方便。   例如MFC扩展DLL除了可使用关键字_declspec(dllexport) 导出类外,还可以使用宏AFX_EXT_CLASS来导出类,而链接到MFC扩展DLL的可执行文件同样使用这个宏来导入类。


总结

机会就像坐公交车,有人上车早,有人上车晚,有人直达车,有人要转车。只要你有决心去目的地,一定可以找到自己的路线!

以上是关于VC/MFC动态库Debug版本下正常,Release版本下错误的主要内容,如果未能解决你的问题,请参考以下文章

MFC读取excel文件程序,在release模式下正常读取,但在debug模式编译没问题,运行就关闭,求高手!

mfc 程序,debug版本正常和release版本异常。

qt : debug版本正常,release版本总提示错误:无法定位程序输入点.......于动态链接库QtCore4.dll 上。

Mfc中release下提示未定义入口点,在debug模式下可以正常运行,这是为啥啊,应该怎么解

DEBUG 和Release的区别

为啥debug编译可以通过,release就无法解析外部符号