利用C++开发运动控制卡的动态链接库,在类的定义有包括了一些WINDOWS的信号量操作,但有些用户在使用QT环境调用时就发生了问题,如下图所示 。

该动态链接库的部分原始代码(头文件)如下所示:

class myNetSocket;
class CSerialPort;class EXPORTS_DEMO MoCtrCard
{
public:MoCtrCard();~MoCtrCard();// RS232 接口McCard_UINT16 MoCtrCard_Initial(McCard_UINT8 ComPort);McCard_UINT16 MoCtrCard_Unload();// 四轴的接口McCard_UINT16 MoCtrCard_MCrlAxisMove(McCard_UINT8 AxisId, McCard_INT8 SpdDir);McCard_UINT16 MoCtrCard_MCrlAxisRelMove(McCard_UINT8 AxisId, McCard_FP32 DistCmnd, McCard_FP32 VCmnd, McCard_FP32 ACmnd);private:CRITICAL_SECTION   mSemCommSync;    ///< 互斥通讯操作 McCard_UINT8 nCmndCnt;              ///< 指令计数器,每下发指令自增1enum ePortLinkType nPortType;      ///< 物理链路类型myNetSocket* cTCPSocket;          ///< 网络接口对像CSerialPort* cRSPort;             ///< RS232接口};

为了实现对 private 部分进行隐藏,达到对用户不可见的目的,上网调研后发现有两种方法可以实现: 1)利用pimpl技术,2)纯虚函数形成接口类

通过对这两种方式的研究,决定使用pimpl方法进行对现有的DLL进行改造;那什么是pimp技术呢?参考MSDN

pimpl idiom 是一种新式 C++ 技术,用于隐藏实现、最小化耦合和分离接口。 Pimpl 是“指向实现的指针”的缩写。细节就不介绍了,而是直接套用实现。impl的实现有固定格式,如下所示:

// my_class.h
class my_class {//  ... all public and protected stuff goes here ...
private:class impl; unique_ptr<impl> pimpl; // opaque type here
};// my_class.cpp
class my_class::impl {  // defined privately here// ... all private data and functions: all of these//     can now change without recompiling callers ...
};
my_class::my_class(): pimpl( new impl )
{// ... set impl values ...
}

在标头实现时,采用了c++的智能指针,因此在头文件中要加入

#include "memory"

在我们的DLL库中,具体实现方式为:

#ifndef _MYCODE_H_
#define _MYCODE_H_#include "memory"#ifdef MCC4DLL_EXPORTS
#define EXPORTS_DEMO _declspec( dllexport )
#else
#define EXPORTS_DEMO _declspec(dllimport)
#endifclass EXPORTS_DEMO MoCtrCard
{
public:MoCtrCard();~MoCtrCard();// RS232 接口McCard_UINT16 MoCtrCard_Initial(McCard_UINT8 ComPort);McCard_UINT16 MoCtrCard_Unload();McCard_UINT16 MoCtrCard_MCrlAxisMove(McCard_UINT8 AxisId, McCard_INT8 SpdDir);McCard_UINT16 MoCtrCard_MCrlAxisRelMove(McCard_UINT8 AxisId, McCard_FP32 DistCmnd, McCard_FP32 VCmnd, McCard_FP32 ACmnd);private:class MoCtrCardImpl;std::unique_ptr<MoCtrCardImpl> m_pImpl;
};#endif

在CPP源文件中实现的Impl如下:

class myNetSocket;
class CSerialPort;
class MoCtrCard::MoCtrCardImpl
{
public:MoCtrCardImpl() {};CRITICAL_SECTION   mSemCommSync;    ///< 互斥通讯操作 McCard_UINT8 nCmndCnt;             ///< 指令计数器,每下发指令自增1enum ePortLinkType nPortType;      ///< 物理链路类型myNetSocket* cTCPSocket;          ///< 网络接口对像CSerialPort* cRSPort;             ///< RS232接口
};MoCtrCard::MoCtrCard():pimpl(new MoCtrCardImpl())
{pimpl->nCmndCnt = 0x00;pimpl->nPortType = ePortNone;                   ///< 物理链路类型pimpl->cTCPSocket = new myNetSocket();        ///< 网络接口对像pimpl->cRSPort = new CSerialPort();           ///< RS232接口InitializeCriticalSection(&pimpl->mSemCommSync);  ///< 收发信号量
}

经过以上改造后,DLL可以直接用在现有的应用程序中,在现有的DEMO程序上进行测试,原始程序不做任何修改,测试成功。

利用Pimpl实现细节隐藏相关推荐

  1. [vb]利用WScript.Shell对象隐藏cmd命令行运行

    1. WScript.Shell(Windows Script Host Runtime Library)是一个对象,对应的文件是C:\WINDOWS\system32\wshom.ocx,Wscri ...

  2. 查看so库中是否有某个定义_论Linux ELF中动态库符号重定义利用 属性/Linker 做隐藏的手法...

    假如libgetthree.so libgetseven.so , 同时这两个so内部都用了internal_do_calculation()函数,并且各自定义了自己的internal_do_calc ...

  3. 利用Python实现图片信息隐藏

    最近上了一门信息隐藏的课,讲的关于技术层面的内容还是蛮多的,但是我也没记住几个.吭吭,言归正传,这两天要交大作业,自己手动实现一种图像信息隐藏,查了一番资料后,决定Python来做(主要是调用包方便) ...

  4. CSS实现中英双语导航栏——利用块级元素隐藏实现

    如何实现中英双语导航栏?(所谓的中英双语导航栏就是导航栏显示的是中文(或英文)然后输入悬浮在其上的时候转成英文(或中文)) 方法有很多,此次记录一种使用块级元素隐藏实现的中英文切换. 上代码: HTM ...

  5. 利用NTFS流文件隐藏

    首先用记事本新建两个文本文档,分别名为"1.txt""2.txt",其内容为"正常文件.数据流文件",打开CMD命令行窗口, 进入两个文件所 ...

  6. 安全之路 —— 利用端口复用技术隐藏后门端口

    简介 前面我们介绍到我们可以用进程注入的方法,借用其他应用的端口收发信息,从而达到穿墙的效果,那么今天介绍一种新的方法,叫做端口复用技术,他能够与其他应用绑定同一个端口,但同时进行端口复用的程序会接管 ...

  7. \t\t健康生活:20个健康小细节隐藏大危害!

    没办法遏制铺天盖地的以讹传讹,至少从专家那里挖来的这些健康秘密也算是种自我保护!吃.住.行,别以为只是小事,你现在所做的事情有可能正在危害你的健康. NO.1饭后不要立即吃水果 现在到餐厅消费,总能在 ...

  8. 利用MATLAB实现WAV音频的LSB信息隐藏

    0. 背景 音频信息隐藏技术就是将秘密数据直接嵌入音频载体中,但不影响原载体的使用价值,也不容易被人的知觉系统觉察或注意到. 音频信息隐藏技术作为信息隐藏技术的一个重要分支,受到越来越多的关注. 近年 ...

  9. 文件隐藏(windows文件隐藏,利用类标识隐藏)

    文件隐藏(windows文件隐藏,利用类标识隐藏) 一:Windows实现文件隐藏 (1)利用Windows默认的隐藏设置 隐藏文件: 1.点击我的电脑–>查看按钮–>点击选项 2.弹出一 ...

最新文章

  1. Cypress USB开发文档列表(积累中)
  2. 1000+ 常用 Python 库一览
  3. CodeForces - 1263A Sweet Problem(思维,水题)
  4. android gradle权威指南pdf_干货 | 携程 Android 10适配踩坑指南
  5. H5移动页面的touch事件与点击穿透问题
  6. Access和sql server的语法区别
  7. MSSQL-最佳实践-Always Encrypted
  8. phpcmsV9中的CSS_PATH是如何定义的
  9. java量_Java 2. 量与常量
  10. Python计算从n个元素中任选i个的组合数C(n,i)
  11. spring配置定时器的时间设置
  12. 如何在一个元素上有多个CSS过渡?
  13. 【负载观测】永磁同步电机的负载观测及前馈补偿
  14. 有界、无界队列对ThreadPoolExcutor执行的影响
  15. android多音字排序,再谈Contacts中姓氏多音字排序错误问题
  16. 获取指定路径,扫描路径下指定类(仿Spring)
  17. Java后台开发常见官方网站汇总
  18. iso12233测试方法_详解ISO12233 Chart(分辨率测试标板)使用方法
  19. 电力系统微型计算机继电保护2018,2018年4月高等教育自学考试电力系统微型计算机继电保护试题及答案...
  20. [html] 网页打印与标准纸张换算时,cm和px是如何换算的?

热门文章

  1. 天龙八部服务器列表文件,天龙八部服务端server目录脚本说明.doc
  2. 培训笔记之WIZnet的主要产品是什么?
  3. 【python笔记九】字典创建、字典增删改查、字典常用操作
  4. ftp 服务部署及ftp 权限设置
  5. 2020 考研数学一 全解析
  6. 【总结】关于photoshop,premiere等Adobe系列软件打开时报错msvcp120.dll丢失的解决方案
  7. USB IP核FPGA调试(三)
  8. 制作RPG独立游戏练习(二)内置渲染管线中实现风格化PBR效果
  9. 指针的点运算和箭头运算(-)
  10. 11.SpringCloud