【实战】CEF框架集成MFC DLL的一些坑

文章目录

  • DLL 导出方式,函数指针的坑
    • 问题出现
    • 问题解决
  • CEF集成MFC
    • afxwin.h
    • 预编译
    • 编译参数修改
  • DLL重命名

MFC作为微软的长期主力开发套件之一,之前很多设备开发的C/S端界面都是通过MFC框架来做的,而在我自己的CEF项目中,会集成很多之前的DLL来完成设备驱动和开发。所以,在CEF项目开发中,肯定会碰到一些和原有的MFC代码集成的工作。

最近收集了几个在集成工作中的坑,自己做个记录,如果能帮到各位,请各位点赞收藏。感谢

DLL 导出方式,函数指针的坑

在其中的一个DLL集成中,这个DLL提供的头文件中有如下的一个函数:

virtual int GetInfo(CString& nVersion) = 0;

这里的形参CString就是MFC框架中的一个字符串库,因为我嫌麻烦,而且判断我在我自己的项目中不需要用到这个函数,也不想在CEF框架中再将MFC的一些库打包进来,这样会降低编译速度,也会增加项目打包后的大小。

所以我第一次的解决方法就是将这个函数从头文件中注释掉。

灾难就是因为这一条注释引起的。

问题出现

注释掉这个函数后,集成顺利进行,而且能顺利控制设备完成一些操作。但发现的问题是,这个DLL提供的所有设备驱动函数中,有部分可以执行,有部分不能执行,而且不能执行的错误很夸张,直接是内存越界,整个程序coredown:

这让我百思不得其解,还找提供DLL的同事增加日志等,结果发现出错的操作函数直接无法进入。

然后又对了编译参数等等,所有的编译参数都对了一遍,结果还是不行。因为这个问题项目停了两三天。

问题解决

直到有一次查看了一下这个DLL的导出方式:

extern "C"
{DLL_API	APIHANDLE* CreateHandleObj();DLL_API void	DeleteHandleObj(APIHANDLE*);
}

也就是说,这个DLL是导出的这个操作类对象,而不是方法。

  1. 如果DLL导出的是方法的话,那么在DLL会把这些方法加载到内存后,将这些方法的内存地址都导出,在程序中调用这些方法的话,就可以直接通过函数指针的方式访问这些地址,完成函数调用。
  2. 如果DLL导出的是类对象的话,那么DLL只会导出这个对象的函数首地址,然后通过函数指针的方式,一个一个的去做函数移动,然后移动到响应内存位置,再完成函数调用。

那么我的问题就出在这里,比如DLL中有20个函数,我将上面那个函数注释掉之后,上层的应用程序就只会认为DLL中有19个函数。

而注释掉的函数如果是在第10个位置的话,那么前9个函数的调用都是没问题的,都可以通过函数指针的方式移动获取到相应的内存地址。

但是这个函数和这个函数后续的函数地址就会发生错位,就会发生上面提到的内存越界访问的问题!!

解决的方案就是恢复这个函数。

CEF集成MFC

如果不注释那个函数,就要解决CString的问题,也就是要集成MFC。

afxwin.h

一般所有的MFC程序都会集成这个头文件: afxwin.h,这个头文件包括了大部分的MFC基础类,当然也包括了CString这个类。

预编译

visual studio提供了预编译的能力,像mfc这种固定的框架头文件,没必要放在业务头文件中,在visual studio创建的项目中,一般都会有一个pch.h的文件,这个头文件中的内容就是visual studio会提前编译好的。

所以,集成MFC的第一步就是将afxwin.h放到pch.h中:

// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。#ifndef PCH_H
#define PCH_H// 添加要在此处预编译的标头
#include "framework.h"#include <afxwin.h>         // MFC 核心组件和标准组件#endif //PCH_H

在visual studio中可以配置这个预编译能力:

编译参数修改

集成MFC还需要修改一个编译参数:

这里需要选择MFC库,使用DLL的话,就表示在你的程序中,MFC的功能是以DLL方式存在的,如果是静态库的话,就会把MFC的lib库打入到你的应用程序里。

我选择的是DLL库。

DLL重命名

最后一个坑,因为我集成MFC的DLL也是一个DLL程序,在没有集成MFC之前,我的DLL命名就是visual studio默认的命名:

BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}

但是集成了MFC之后,也就是上面提到的集成了MFC的DLL之后,再编译就会提示DllMain重定义,也就是说和MFC的DLL中的DllMain冲突了,所以这里需要改个名字即可:

BOOL APIENTRY DllMainMyOwn( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}

顺利解决问题!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2799575.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

顺序表详解(如何实现顺序表)

文章目录 前言 在进入顺序表前&#xff0c;我们先要明白&#xff0c;数据结构的基本概念。 一、数据结构的基本概念 1.1什么是数据结构 数据结构是由“数据”和“结构”两词组合而来。所谓数据就是&#xff1f;常见的数值1、2、3、4.....、姓名、性别、年龄&#xff0c;等。…

React基础-webpack+creact-react-app创建项目

学习视频&#xff1a;学习视频 2节&#xff1a;webpack工程化创建项目 2.1.webpack工程化工具&#xff1a;vite/rollup/turbopak; 实现组件的合并、压缩、打包等&#xff1b; 代码编译、兼容、校验等&#xff1b; 2.2.React工程化/组件开发 我们可以基于webpack自己去搭建…

LeetCode | 寻找两个正序数组的中位数 Python C语言

Problem: 4. 寻找两个正序数组的中位数 文章目录 思路解题方法Code结果结果一些思考 思路 先合并&#xff0c;后排序&#xff0c;最后找中间轴。 解题方法 由解题思路可知 Code 这是python3的代码。 class Solution(object):def findMedianSortedArrays(self, nums1, num…

IDEA 2021.3激活

1、打开idea&#xff0c;在设置中查找Settings/Preferences… -> Plugins 内手动添加第三方插件仓库地址&#xff1a;https://plugins.zhile.io搜索&#xff1a;IDE Eval Reset 插件进行安装。应用和使用&#xff0c;如图

Spring 类型转换、数值绑定与验证(一)— DataBinder

DataBinder 是Spring用于数据绑定、类型转换及验证的类。使用场景有&#xff1a;1&#xff09;xml配置文件定义bean,Spring 内部使用DataBinder 来完成属性的绑定&#xff1b;2&#xff09;Web请求参数绑定&#xff0c;在Spring MVC 中&#xff0c;Controller的方法参数通常会自…

基于机器学习的青藏高原高寒沼泽湿地蒸散发插补研究_王秀英_2022

基于机器学习的青藏高原高寒沼泽湿地蒸散发插补研究_王秀英_2022 摘要关键词 1 材料和方法1.1 研究区概况与数据来源1.2 研究方法 2 结果和分析2.1 蒸散发通量观测数据缺省状况2.2 蒸散发与气象因子的相关性分析2.3 不同气象因子输入组合下各模型算法精度对比2.4 随机森林回归模…

《图解设计模式》笔记(一)适应设计模式

图灵社区 - 图解设计模式 - 随书下载 评论区 雨帆 2017-01-11 16:14:04 对于设计模式&#xff0c;我个人认为&#xff0c;其实代码和设计原则才是最好的老师。理解了 SOLID&#xff0c;如何 SOLID&#xff0c;自然而然地就用起来设计模式了。Github 上有一个 tdd-training&…

第3.4章:StarRocks数据导入-Routine Load

注&#xff1a;本篇文章阐述的是StarRocks-3.2版本的Routine Load导入机制 一、概述 Routine Load&#xff08;例行导入&#xff09;支持用户提交一个常驻的导入任务&#xff0c;可以将消息流存储在 Kafka 的Topic中&#xff0c;通过订阅Topic 中的全部或部分分区的消息&#…

多个.C 文件关于全局变量如何使用

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary_walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

C语言新手写函数中出现数组时运行bug的解决

一.发现问题&#xff1a; 这是我今天写代码的一小部分&#xff0c;是创建一个数组&#xff0c;然后函数init&#xff08;&#xff09;是初始化数组&#xff0c;代码如下&#xff1a; void init(int arr[10],unsigned int k) {int i 0;for (i 0; i < k; i) {arr[i] 0;} …

深度学习系列60: 大模型文本理解和生成概述

参考网络课程&#xff1a;https://www.bilibili.com/video/BV1UG411p7zv/?p98&spm_id_frompageDriver&vd_source3eeaf9c562508b013fa950114d4b0990 1. 概述 包含理解和分类两大类问题&#xff0c;对应的就是BERT和GPT两大类模型&#xff1b;而交叉领域则对应T5 2.…

机器学习基本概念(李宏毅课程)

目录 一、概念:1、机器学习概念:2、深度学习概念&#xff1a; 二、深度学习中f(.)的输入和输出&#xff1a;1、输入&#xff1a;2、输出&#xff1a; 三、三种机器学习任务&#xff1a;1、Regression回归任务介绍&#xff1a;2、Classification分类任务介绍&#xff1a;3、Stru…

【Python】OpenCV-图片差异检测与标注

图片差异检测与标注 在图像处理领域中&#xff0c;检测两张图片之间的差异是一项重要的任务。本文将介绍一个使用OpenCV库进行图片差异检测的简单示例代码&#xff0c;并详细注释每个步骤。 1. 引言 图片差异检测是在两张图片之间寻找差异点或区域的过程。这项技术可用于监测…

http和https的区别(简述)

HTTP&#xff08;HyperText Transfer Protocol&#xff09;和HTTPS&#xff08;HTTP Secure&#xff09;都是用于在客户端和服务器之间传输数据的协议&#xff0c;但它们在安全性方面有重要的区别。 1.HTTP: 概述&#xff1a; HTTP是一种用于传输超文本的协议&#xff08;超文…

Javascript中var和let之间的区别

文章目录 一.变量提升(声)二.let和var的区别 区别&#xff1a; 1、var有变量提升&#xff0c;而let没有&#xff1b; 2、let不允许在相同的作用域下重复声明&#xff0c;而var允许&#xff1b; 3、let没有暂时性死区问题&#xff1b; 4、let创建的全局变量没有给window设置对应…

【PX4学习笔记】13.飞行安全与炸机处理

目录 文章目录 目录使用QGC地面站的安全设置、安全绳安全参数在具体参数中的体现安全绳 无人机炸机处理A&#xff1a;无人机异常时控操作B&#xff1a;无人机炸机现场处理C&#xff1a;无人机炸机后期维护和数据处理D&#xff1a;无人机再次正常飞行测试 无人机飞行法律宣传 使…

基于springboot+vue的B2B平台的医疗病历交互系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

R cox回归 ggDCA报错

临床预测模型的决策曲线分析&#xff08;DCA&#xff09;&#xff1a;基于ggDCA包 决策曲线分析法&#xff08;decision curve analysis&#xff0c;DCA&#xff09;是一种评估临床预测模型、诊断试验和分子标记物的简单方法。 我们在传统的诊断试验指标如&#xff1a;敏感性&a…

golang实现延迟队列(delay queue)

golang实现延迟队列 1 延迟队列&#xff1a;邮件提醒、订单自动取消 延迟队列&#xff1a;处理需要在未来某个特定时间执行的任务。这些任务被添加到队列中&#xff0c;并且指定了一个执行时间&#xff0c;只有达到指定的时间点时才能从队列中取出并执行。 应用场景&#xff1…

[ Python+OpenCV+Mediapipe ] 实现对象识别

一、写在前面 本文所用例子为个人学习的小结&#xff0c;如有不足之处请各位多多海涵&#xff0c;欢迎小伙伴一起学习进步&#xff0c;如果想法可在评论区指出&#xff0c;我会尽快回复您&#xff0c;不胜感激&#xff01; 所公布代码或截图均为运行成功后展示。 二、本文内容…