通过DLL导出类指针来传递及使用对象

DLL开发是windows编程中经常用到的一种技术。从DLL中可以导出函数、变量、还有类。这个通过VS的win32应用程序向导生成一个win32DLL(附加选项选中【导出符号】),生成的代码有相应示例。但是,在实际开发过程中,我们会发现从DLL中导出类是件不太靠谱的事情。原因可能是DLL和调用DLL的应用程序是用不同编译器或者编译器的不同版本,也可能是DLL和应用程序使用的内存堆不一样。总之,使用DLL传递对象不是一件稳定的事情。

再说,我们也没见过Win32API和COM接口直接传递对象出来不是?我们能确定可以稳定传递的只有基本数据类型。

但是有时候,我们又需要直接使用DLL里面的对象,怎么办?这中情况下,可以进行一些转换,通过传递指针的方式来使用DLL里的对象。毕竟指针也是基本数据类型。这也是COM接口传递对象的方式。接口的具体实现也有不同的方式,这里就来举个例,实现一种。

首先,在任意现有的解决方案中添加一个WIN32 DLL项目。项目名称就叫w3 。如图1、图2。通过DLL导出类指针来传递及使用对象_第1张图片

图1

通过DLL导出类指针来传递及使用对象_第2张图片

图2


点击完成后,我们可以看到自动生成的项目里头文件加源文件一个只有5个。如图3。

通过DLL导出类指针来传递及使用对象_第3张图片

图3

向项目中加入内容如下的头文件。

//IW3d.h
#pragma once

#include 

class IDemo
{
public:
	virtual std::string GetString(void)=0;
	virtual bool GetRString(std::string & r)=0;
};

IDemo* ID_GetInstance(void);
typedef IDemo* (*pfnGetInstanceID)(void);
这个头文件声明了一个名为IDemo的接口类,以及获取该类的实例的指针的函数ID_GetInstance(),还有对应的函数指针。
声明了接口之后,再加入相应的继承及实现。

//W3dImpl.h
#pragma once
#include "iw3d.h"

class W3dImpl :	public IDemo
{
public:
	W3dImpl(void);
	~W3dImpl(void);

	virtual std::string GetString(void);
	virtual bool GetRString(std::string & r);
};

//W3dImpl.cpp
#include "StdAfx.h"
#include "W3dImpl.h"

W3dImpl::W3dImpl(void)
{
}

W3dImpl::~W3dImpl(void)
{
}

std::string W3dImpl::GetString(void)
{
	return "This is a demo for export object.";
}

bool W3dImpl::GetRString(std::string & r)
{
	r = "This is string object";
	return true;
}
函数的实现中,为了简化,直接返回了一个字符串。

再加入一个单例模板的头文件。注意,这里单例并不是必须的。但是导出了对象指针,就必须考虑对象的生命周期。这里使用单例,是为了简化外部的处理。调用方不必操心对象的生命周期问题,由DLL自己处理。

//SingleTonTemplate.h
#ifndef _SINGLETON_TEMPLATE_H_
#define _SINGLETON_TEMPLATE_H_

template
class SingleTon
{
public:
	static T & GetInstance()
	{
		return t;
	}

protected:
	SingleTon(){}
	SingleTon(const SingleTon & src){}
	~SingleTon(){}
	
	static T t;
};

template
T SingleTon::t;

#endif

添加一个模块定义文件w3.def

LIBRARY	"w3"
EXPORTS
	ID_GetInstance

再向w3.cpp中添加ID_GetInstance()的函数实现,及需要的头文件。

// w3.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "W3dImpl.h"
#include "SingleTonTemplate.h"

IDemo* ID_GetInstance(void)
{
	return &(SingleTon::GetInstance());
}
OK!现在编译一下,就大功告成了。

看一下调用的例子

#include "stdafx.h"
#include "..\w3\iw3d.h"
#include 
#include 

int _tmain(int argc, _TCHAR* argv[])
{
	HMODULE h = ::LoadLibrary(_T("w3.dll"));
	pfnGetInstanceID pfnGetInstance = (pfnGetInstanceID)::GetProcAddress(h,"ID_GetInstance");
	IDemo* pImpl = pfnGetInstance();
	std::string str = pImpl->GetString();
	std::cout<GetRString(str);
	std::cout<






你可能感兴趣的:(C++)