c++DLL封装DLL问题

C++ 同时被 2 个专栏收录
23 篇文章 0 订阅
1 篇文章 0 订阅

由于工作需要,自己手动封装一个DLL,简单说就是自己写一个DLL来加载另外一个DLL

第一次写博客,记录自己的一些经验,方便以后查看,少走弯路,新手可以看看,大神略过。

我封装的DLL是阿里的消息队列C++的SDK,阿里只能静态加载,配置麻烦,所以封装使用。

在编写测试过程中出过很多问题,因为我是第一次封装,小问题就不做记录,几个稍微大的问题,第一个封装完成调用运行的时候报错,提示使用错误的调用方式,在网上找了很久都是说调用约定不一致就是所谓的__stdcall __cdecl的问题,但是都是我自己定义好的,同样的工程环境,也是各种琢磨测试也没有用,后来转用release版本,发现就没有问题,对那个问题还是没能很清楚,待以后研究研究,有的时候可能debug版本有问题不妨试一试release版本。

再一个问题就是我调用封装DLL接口传入的参数问题,参入的数据和DLL传出的数据对不上,各种查看,改变传入方式,分配内存等等试了很多,仍然没用,当时很是无助,也咨询过大神,也没有找到个所以然,后来发现是定义宏中char数组和string的问题,两边的数据类型一定要是一致的,不然这两者用起来不报错,但是值就是对不上,很是心塞。

还有一个最后路径的问题,动态加载DLL是可以设置路径的,但是我的DLL里面是静态加载的阿里的DLL,所以这种情况下只能把阿里的DLL和应用程序放在一个目录下面,这样违背了初衷,后来查到资料添加系统环境变量,或者将静态加载的DLL放到系统环境变量的目录下面,就是环境变量下面path中设置的目录,具体怎么设置可以搜一下,很简单,但是我当时设置了环境变量之后还是显示加载DLL未能扎到指定模块,我用DLL调试又没有问题(只是自我测试的小程序),当时要让服务器的插件调用,不能调试,日志输出也看不出问题,很是头痛,这种情况下可以自己写简单的测试程序可以运行的,直接放到服务器上运行,发现是缺少运行库,添加上运行库,完美解决。


第一次做,前后几天,完成之后发现很简单,但是一些小的细节还是要注意。


贴上我封装的DLL的头文件代码,很简单,可以作为通用DLL封装头。

#pragma once

#include <string>
#include <vector>

#ifdef OSN_DLL  
#define DLL_API extern "C" __declspec(dllexport)  
#else  
#define DLL_API extern "C" __declspec(dllimport)  
#endif

//消息信息结构
typedef struct _SMSG_INFO
{
char strTag[16];
char strKey[16];
char strMsgID[255];
char strMsgBody[255];
}SMSG_INFO,*PSMSG_INFO;
/* 
    设计这个接口类的作用: 
    能采用动态调用方式使用这个类 
*/  
class CONSInterface  
{  
public:  
    virtual ~CONSInterface(void)
    {  
    }  

virtual void   setConsumerId(const char* chConsumerId) = 0;//您在MQ控制台申请的consumerId
virtual void   setProducerId(const char* chProducerId) = 0;//在ONS控制台申请的producerId
virtual void   setPublishTopics(const char* chPublishTopics) = 0;//在ONS 控制台申请的msg topic
virtual void   setAccessKey(const char* chAccessKey) = 0;//ONS AccessKey
virtual void   setSecretKey(const char* chSecretKey) = 0;//ONS SecretKey

virtual void   StartProducer() = 0;
virtual void   StartConsumer() = 0;
virtual void   EndProducer() = 0;
virtual void   EndConsumer() = 0;

virtual bool  SendMsgQueue(const char* pTag, const char* pKey, const char* pMsgBody, const char* strError) = 0;//发送消息到消息队列
virtual int  GetMsgQueue(SMSG_INFO *pMsg) = 0;//获取消息队列信息,返回消息,传入指针为返回地址
};

typedef CONSInterface* (*ONSCreate_t)();

#ifndef OSN_DLL
#include <Windows.h>

class CONSFactory
{
private:
HMODULE         m_lib;
ONSCreate_t     m_pfnONSCreate;
public:
//--- constructor
CONSFactory(LPCSTR lib_path=NULL):m_lib(NULL) 
{
Init(lib_path);
}
//--- destructor
~CONSFactory()
{
if(m_lib)
{
m_pfnONSCreate =NULL;
::FreeLibrary(m_lib); 
m_lib=NULL;
}
}
//--- initialization
inline void Init(LPCSTR lib_path=NULL)
{
char path[256]="";
//---
if(lib_path!=NULL) 
{
strcpy_s(path,lib_path);
path[sizeof(path)-1]=0;
}
else               
{ 
strcpy_s(path,"Doo_ONSdll.dll"); 
path[sizeof(path)-1]=0; 
}
//---
if(m_lib) 
::FreeLibrary(m_lib);
if((m_lib=::LoadLibraryA(path))!=NULL)
{
m_pfnONSCreate =reinterpret_cast<ONSCreate_t>(::GetProcAddress(m_lib,"CreateONSInterface"));
}
else
{
m_pfnONSCreate =NULL;
}
//---
}
//--- winsock startup/cleanup
inline int WinsockStartup() const
{
WSADATA wsa;
return(WSAStartup(0x0202,&wsa)!=0 ? 2:0);
}
inline void WinsockCleanup() const 
{
WSACleanup();
}
//---
inline int IsValid() const 
{
return(m_lib!=NULL && m_pfnONSCreate!=NULL) ? TRUE:FALSE;
}
inline CONSInterface* Create() const
{
if(m_pfnONSCreate) 
return (*m_pfnONSCreate)();

return NULL;
}
};
#endif


  • 1
    点赞
  • 0
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值