跨越C#和C++的单件(SINGLETON)模式
来源:互联网 发布:怎么设置淘宝客 编辑:程序博客网 时间:2024/05/17 01:33
无论是使用C#语言还是C++语言开发出一个单件模式对于大多数人来说都不是太难的一件事。但是使用.Net平台开发项目的时候,一个解决方案中往往会有C#和C++两种工程(没办法,谁让C#有那么好的界面功能,以及那么强的XML和数据库操作功能J)。如何使一个类对象实例贯穿在C#和C++两种工程中,并且使它在整个过程中有且仅有一个?也就是说,这是不仅仅是一个工程中的单件,而是一个解决方案中的单件。相信这一定是任何一个具有.Net平台开发经验的程序员急切想了解的话题。
本文中给出了一个解决方案。这是一个从实际项目开发中总结出来的案例,目的就是要在软件运行过程中保证仅有的一个工程管理类实例存在,而对该管理类实例的使用却要贯穿整个解决方案(C#和C++两种工程)。
首先让我们来了解一下.Net框架类库提供的两个重要相关类型的使用:
GCHandleType 枚举--表示 GCHandle 类可以分配的句柄的类型。
命名空间: System.Runtime.InteropServices
程序集: mscorlib(在 mscorlib.dll 中)
成员名称
说明
Normal
此句柄类型表示不透明句柄,这意味着无法通过此句柄解析固定对象的地址。可以使用此类型跟踪对象,并防止它被垃圾回收器回收。当非托管客户端持有对托管对象的唯一引用(从垃圾回收器检测不到该引用)时,此枚举成员很有用。
Pinned
此句柄类型类似于 Normal,但允许使用固定对象的地址。这将防止垃圾回收器移动对象,因此将降低垃圾回收器的效率。需要使用 Free 方法可尽快释放已分配的句柄。 (Use the Free method to free the allocated handle as soon as possible. )
Weak
此句柄类型用于跟踪对象,但允许回收该对象。当回收某个对象时,GCHandle 的内容归零。在终结器运行之前,Weak 引用归零,因此即使终结器使该对象复活,Weak 引用仍然是归零的。
WeakTrackResurrection
该句柄类型类似于 Weak,但如果对象在终结过程中复活,此句柄不归零。
GCHandle 结构--提供从非托管内存访问托管对象的方法。
命名空间: System.Runtime.InteropServices
程序集: mscorlib(在 mscorlib.dll 中)
名称
说明
IsAllocated
获取一个值,该值指示是否分配了句柄。
Target
获取或设置该句柄表示的托管对象。
Alloc
传入一个托管对象,为这个指定的对象分配句柄。缺省为该对象分配GCHandleType. Normal 句柄。
ToIntPtr
返回 GCHandle 对象的内部整数表示形式。
FromIntPtr
传入GCHandle代表的某个托管对象的内部整数表示,返回一个新创建GCHandle 对象。
Free
释放 GCHandle。调用方必须确保对于给定的句柄,只调用 Free 一次。
GCHandle 类与 GCHandleType 枚举结合使用以创建对应于任何托管对象的句柄。此句柄可为四种类型之一:Weak、WeakTrackResurrection、Normal 或 Pinned。分配了句柄以后,在非托管客户端保留唯一的引用时,可以使用 GCHandle 防止垃圾回收器回收托管对象。如果没有这样的句柄,则在该对象代表非托管客户端完成工作以前,有可能被垃圾回收器回收。
WNDENUMPROC lpEnumFunc,
LPARAM lParam );
HWND hwnd,
LPARAM lParam );
public class LibWrap
{
// 传入一个托管对象作为LPARAM参数.(经过IntPtr指针的转换)
// 为非托管函数声明一个托管的原型
[ DllImport( "user32.dll" )]
public static extern bool EnumWindows( CallBack cb, IntPtr param );
}
调用函数
{
public static void Main()
{
TextWriter tw = System.Console.Out;
GCHandle gch = GCHandle.Alloc( tw );
CallBack cewp = new CallBack( CaptureEnumWindowsProc );
LibWrap.EnumWindows( cewp, (IntPtr)gch );
gch.Free();
}
private static bool CaptureEnumWindowsProc( int handle, IntPtr param )
{
GCHandle gch = (GCHandle)param;
TextWriter tw = (TextWriter)gch.Target;
tw.WriteLine( handle );
return true;
}
}
{
public class Project
{
private static Project activeProject = null;
private Project() { }
public static Project ActiveProject
{
get
{
if (activeProject == null)
activeProject = new Project();
return activeProject;
}
}
public bool DoWorkAboutXML()
{
//...
return true;
}
public bool DoWorkAboutDB()
{
//...
return true;
}
}
}
由于Project的实现采用了单件模式,因此可以保证在任何时刻都只可能有一个Project对象实例存在。通过Project::ActiveProject属性实现该唯一对象的访问。
首先创建一个支持CLR的托管工程,声明一个C++类--AcPpProject,在类型定义使用 GCHandle 创建对应于托管对象Project::ActiveProject的句柄。从而可以效防止在该对象代表非托管客户端完成工作以前被垃圾回收器回收。 Class AcPpProject类型中通过一个void *指向GCHandle object.
class __declspec(dllexport) AcPpProject
{
public:
AcPpProject();
~AcPpProject();
bool DoWorkAboutXML();
bool DoWorkAboutDB();
protected:
void* m_pProjectGCHandle;
};
// ProjectManagerMgd.cpp
#include "ProjectManagerMgd.h"
using namespace ProjectManager;
using namespace System::Runtime::InteropServices;
AcPpProject::AcPpProject()
{
GCHandle gch = GCHandle::Alloc(Project::ActiveProject);
m_pProjectGCHandle = GCHandle::ToIntPtr(gch).ToPointer();
}
AcPpProject::~AcPpProject ()
{
GCHandle gch = GCHandle::FromIntPtr(System::IntPtr(m_pProjectGCHandle));
gch.Free();
m_pProjectGCHandle = 0;
}
对于Project中的每一个实例方法,在AcPpProject都有相应的对应方法定义,并通过将m_pProjectGCHandle还原为原来的Project对象来具体实现调用。因此AcPpProject中的对应方法函数都是对Project中的方法的包装实现。
{
Project^ pProject = nullptr;
if (pProjectGCHandle != 0)
{
GCHandle gch = GCHandle::FromIntPtr(System::IntPtr(pProjectGCHandle));
pProject = static_cast<Project^>(gch.Target);
}
return pProject;
}
bool AcPpProject::DoWorkAboutXML()
{
Project^ pProject = GETPROJECT(m_pProjectGCHandle);
if (pProject == nullptr)
{
return false;
}
return pProject->DoWorkAboutXML();
}
bool AcPpProject::DoWorkAboutDB()
{
Project^ pProject = GETPROJECT(m_pProjectGCHandle);
if (pProject == nullptr)
{
return false;
}
return pProject->DoWorkAboutDB();
}
- 跨越C#和C++的单件(SINGLETON)模式
- 多线程安全的Singleton单件模式在C++,java与C#下的实现
- c#平台下singleton单件模式
- singleton单件模式
- Singleton (单件模式)
- 单件模式(Singleton)
- singleton 单件模式
- 单件模式[Singleton]
- SingleTon单件模式
- 单件模式(Singleton)
- Singleton 单件模式
- 单件模式-Singleton
- Singleton单件模式
- 【单件模式-Singleton】
- 单件模式(Singleton)
- 单件模式(Singleton)和锁定(lock)
- Python和Singleton (单件)模式
- Python和Singleton (单件)模式
- 武陵区财政局内网实施方案
- 关键词之外链
- 初学PHPZ碰到mktime()函数
- asp.net下大文件上传知识整理
- 程序员的好消息——中国猪肉紧张的状况有望缓解。
- 跨越C#和C++的单件(SINGLETON)模式
- VS.NET中自定义安装程序制作经验总结
- Page.SmartNavigation 属性
- 在DataAdapter中开启事务
- 类型构造器
- 使用AutoMake轻松生成Makefile
- C#泛型集合揽胜
- Tech2007南京技术大会
- 利润侵蚀工资,税收侵蚀工资,税收机制对分配公平的矫正作用非但没能发挥,反而更加剧了分配的不公平性