CLR组件开发之 基于C++ dll 与C++/CLI dll与C#的数据类型对应关系

  模块化组件化实现独立的功能模块是软件设计的良好习惯,一般用实现为DLL。普通的DLL对外提供接口是采用导出函数接口,如果接口数量不大,只是50个以内,这种方式很适合;如果对外接口有上百个,导出函数接口就完全破坏了软件模块化分层设计的理念,使用接口非常麻烦,此情形采用C++/CLI导出类方式实现比较适合,即核心实现先C++ DLL,然后C++/CLI直接调用C++ DLL导出类,对外第三方工程提供CLI类接口。3种开发语言常用的数据类型对应关系如下表所示:

MFC C++ C++/CLI C# 说明
int int int  
bool bool bool  
byte byte byte  
long long long long long  
int& int% ref int int形参返回值
HWND IntPtr IntPtr  
CString String^ String  
int Color Color 需在CLI工程写int与Color转换函数
long long DateTime DateTime 需在CLI工程写long long
与DateTime转换函数
CChart* CChart* IntPtr  
  CChart^ CChart 都是托管类型对象
  CCurve^ CCurve 都是托管类型对象
  List<CCurve^>^ List<ChartObject> 都是托管类型对象
  CCurve^% ref Ccurve  
  array<Color>^ Color[]  
  property 属性 直接属性取值赋值
       

需要特别说明的是:

1>需要函数形参返回int值时,C++定义为int&,CLI定义为int%,C#定义为ref int。如GetChartSize(int& w, int& h) --> GetChartSize(int% w, int% h) --> GetChartSize(ref int w, ref int h);

2>需要颜色定义时,C++不支持Color只能用int,CLI支持Color,C#支持Color,因为int和Color类型的内存不一样,需要中间层CLI把int 与 Color相互转换(DateTime类型也是如此)。转换函数如下:

 1         static UINT32 Color2UInt(Color color)
 2         {
 3             UINT32 argb = 0;
 4         //    argb += color.A << 24;
 5             argb += color.R << 0;
 6             argb += color.G << 8;
 7             argb += color.B << 16;
 8             return argb;
 9         }
10         static Color UInt2Color(UINT32 c)
11         {
12             Color clr;
13             clr = clr.FromArgb((c >> 0) & 255, (c >> 8) & 255, (c >> 16) & 255);
14             return clr;    
15         }

 

3>CLI类加^,等同于C#的类,都是托管对象。

那么C++对象是怎么与C#对应上的呢?他们无法直接对应,得通过CLI层转换。得在CLI层同时维护C++类指针与CLI类引用,并且让他们关联上。对C#使用CCurve^托管对象,对内维护C++类CCurve*指向的非托管内存。具体请看下一节CLI工程源码。

 

4> 属性的实现。C++使用setXXX和GetXXX函数,CLI使用property即set和get方法,C#直接访问变量。示例如下:

 1 //C++工程 LineCurve.h声明
 2 int m_nLineWidht;
 3 int GetLineWidth();
 4 void SetLineWidth(int w);
 5 
 6 //C++工程 LineCurve.cpp实现
 7 int CLineCurve::GetLineWidth()
 8 {
 9     return m_nLineWidht;
10 }
11 void CLineCurve::SetLineWidth(int w)
12 {
13     m_nLineWidht = w;
14 }
15 
16 
17 //-----------------------------------------------------
18 //CLI工程 LineCurve.h声明
19 property int LineWidth {
20     int get();
21     void set(int value);
22 }
23 
24 //CLI工程 LineCurve.cpp实现
25 int LineCurve::LineWidth::get()
26 {
27     return m_cLineCurve->GetLineWidth();
28 }
29 void LineCurve::LineWidth::set(int value)
30 {
31     m_cLineCurve->SetLineWidth(value);
32 }
33 
34 
35 //-----------------------------------------------------
36 //C#工程
37 LineCurve lcurve = new LineCurve();
38 lcurve.LineWidth = 3;
39 int lw = lcurve.LineWidth;

 


posted @ 2023-07-09 10:32  浮云绘图  阅读(113)  评论(0编辑  收藏  举报