刚开始参加一个项目,工程的代码以前的人已经写得差不多了。GUI是用C#写的,底层调用的是C++的DLL。
C++的DLL工程里面全都是些C语言的函数而已,单纯的从DLL中导出再对应到一个C#的类里面。实在很难接受这样子的设计,美其名曰C#是一个比C++更简单纯面向对象的语言,好像他们真正的明白面向对象是什么一样,可是底层还是要用C++,让人气不过的就是其实用的是C语言。这是什么样子的设计,是面向对象的设计吗?那么多的底层DLL工程代码全都是用C语言写的函数而已。如此多的核心代码都是用C语言写的,可以想象这个工程会多么的难以维护;我只是一个初级的程序员,这样的代码我看着就是想吐。
可能是有一点很恶心,C#好像是不可能直接使用用C++所写的类,可是我们也还是有办法做到让C#本质上还是使用的用C++代码产生的对象的。在DLL里面我们只是简单的用一些导出的接口函数让C#使用,而这个DLL内部本质上还是用一个(或者多个,还可以是一个类系统)对象来维护的。可是他们就是不愿意这样子做,让我们现在的工作很难进行,写的代码不能入目。
下面是我写的一个简单的例子程序,虽然这个没有什么,可是看起来心里舒服多了。
一、用VS2005建立一个解决方案unlearn
二、在解决方案unlearn中添加一个VC++的Win32 DLL工程CppDLL
三、添加头文件MyClass.h 内容入下:
1#ifndef __MYCLASS_H__
2#define __MYCLASS_H__
3
4#include <iostream>
5#include <string>
6
7using namespace std;
8
9class CMyClass
10{
11public:
12 CMyClass(string name)
13 {
14 if (name.size() <= static_cast<size_t>(0))
15 {
16 objName = "noname";
17 }
18 objName = name;
19 }
20
21 void PrintName()
22 {
23 cout << objName << endl;
24 }
25
26 bool MallocString(char *&pStr, int &size)
27 {
28 pStr = new char[5];
29 pStr[0] = 'a';
30 pStr[1] = 'b';
31 pStr[2] = 'c';
32 pStr[3] = 'd';
33 pStr[4] = '\0';
34 size = 5;
35 return true;
36 }
37
38 bool FreeString(char *&pStr)
39 {
40 if (pStr == 0)
41 {
42 return false;
43 }
44 cout << pStr << endl;
45 delete []pStr;
46 pStr = 0;
47 return true;
48 }
49
50private:
51 string objName;
52};
53
54#endif // __MYCLASS_H__
三、添加头文件ExportFunc.h 内容如下:
1#ifndef __EXPORTFUNC_H__
2#define __EXPORTFUNC_H__
3
4#include "MyClass.h"
5
6bool CreateObj(char *name);
7bool DeleteObj();
8void OperateObj();
9bool CreateString(char *&pStr, int &size);
10bool FressString(char *&pStr);
11
12#endif // __EXPORTFUNC_H__
13
14四、添加源文件ExportFunc.cpp 内容如下:
15
16#include "stdafx.h"
17#include "ExportFunc.h"
18
19CMyClass *pObj = NULL;
20
21bool CreateObj(char *name)
22{
23 DeleteObj();
24 pObj = new CMyClass(string(name));
25 return true;
26}
27
28bool DeleteObj()
29{
30 if (pObj != NULL)
31 {
32 delete pObj;
33 pObj = NULL;
34 }
35 return true;
36}
37
38void OperateObj()
39{
40 if (pObj == NULL)
41 {
42 return ;
43 }
44 pObj->PrintName();
45}
46
47bool CreateString(char *&pStr, int &size)
48{
49 if (pObj == NULL)
50 {
51 return false;
52 }
53 return pObj->MallocString(pStr, size);
54}
55
56bool FressString(char *&pStr)
57{
58 if (pObj == NULL)
59 {
60 return false;
61 }
62 return pObj->FreeString(pStr);
63}
四、添加模块定义文件CppDll.def 内容如下:
1LIBRARY "CppDll"
2EXPORTS
3 CreateObj
4 DeleteObj
5 OperateObj
6 CreateString
7 FressString
五、在项目属性设置默认
六、在解决方案unlearn中添加一个C#的控制台应用程序项目CSApp
七、项目属性->生成->输出路径改为"..\debug\" (其实就是让两个项目的输出结果放在一个地方,debug版本C++工程默认的输出路径是这个)
八、修改Program.cs文件 内容如下:
1using System.Runtime.InteropServices;
2
3namespace CSApp
4{
5 class TestDll
6 {
7 [DllImport("CppDll.dll", CharSet = CharSet.Ansi)]
8 public static extern bool CreateObj(string name);
9 [DllImport("CppDll.dll", CharSet = CharSet.Ansi)]
10 public static extern bool DeleteObj();
11 [DllImport("CppDll.dll", CharSet = CharSet.Ansi)]
12 public static extern void OperateObj();
13 [DllImport("CppDll.dll", CharSet = CharSet.Ansi)]
14 public static extern bool CreateString(out IntPtr pStr, out int size);
15 [DllImport("CppDll.dll", CharSet = CharSet.Ansi)]
16 public static extern bool FressString(out IntPtr pStr);
17 }
18
19 class Program
20 {
21 static void Main(string[] args)
22 {
23 IntPtr pStr = IntPtr.Zero;
24 int size = 0;
25 TestDll.CreateObj("huymou");
26 TestDll.OperateObj();
27 TestDll.CreateString(out pStr, out size);
28 TestDll.FressString(out pStr);
29 TestDll.DeleteObj();
30 }
31 }
32}
把CSApp设为启动工程就可以了。这个例子很简单,C#只是简单调用了DLL中的几个导出的接口函数,它们其实没有做什么,就有CreateObj和DeleteObj很重要,其它的函数只是简单的把CMyClass的公共成员函数包了一下。这样子就可以用C#使用C++所写的类了,我们核心的代码还是用面向对象的方法来实现的,而且本质上我们是用了对象来帮助我们做事的。
当然可能本人见识不够,不知道还有更好的办法,现在我也是刚刚想到这些的,好多都可以完善。最后还是一句话,我永远喜欢C++,我相信C++可以做得更好、更出色,不想看到乱用C++的事情出现;有些人乱用了C++,还说C++一大堆的坏话。真正大型的工程其实C++才是最适合的。