剛開始參加一個項目,工程的代碼以前的人已經(jīng)寫得差不多了。GUI是用C#寫的,底層調(diào)用的是C++的DLL。
C++的DLL工程里面全都是些C語言的函數(shù)而已,單純的從DLL中導(dǎo)出再對應(yīng)到一個C#的類里面。實在很難接受這樣子的設(shè)計,美其名曰C#是一個比C++更簡單純面向?qū)ο蟮恼Z言,好像他們真正的明白面向?qū)ο笫鞘裁匆粯樱墒堑讓舆€是要用C++,讓人氣不過的就是其實用的是C語言。這是什么樣子的設(shè)計,是面向?qū)ο蟮脑O(shè)計嗎?那么多的底層DLL工程代碼全都是用C語言寫的函數(shù)而已。如此多的核心代碼都是用C語言寫的,可以想象這個工程會多么的難以維護(hù);我只是一個初級的程序員,這樣的代碼我看著就是想吐。
可能是有一點很惡心,C#好像是不可能直接使用用C++所寫的類,可是我們也還是有辦法做到讓C#本質(zhì)上還是使用的用C++代碼產(chǎn)生的對象的。在DLL里面我們只是簡單的用一些導(dǎo)出的接口函數(shù)讓C#使用,而這個DLL內(nèi)部本質(zhì)上還是用一個(或者多個,還可以是一個類系統(tǒng))對象來維護(hù)的??墒撬麄兙褪遣辉敢膺@樣子做,讓我們現(xiàn)在的工作很難進(jìn)行,寫的代碼不能入目。
下面是我寫的一個簡單的例子程序,雖然這個沒有什么,可是看起來心里舒服多了。
一、用VS2005建立一個解決方案unlearn
二、在解決方案unlearn中添加一個VC++的Win32 DLL工程CppDLL
三、添加頭文件MyClass.h 內(nèi)容入下:
1
#ifndef __MYCLASS_H__
2
#define __MYCLASS_H__
3
4
#include <iostream>
5
#include <string>
6
7
using namespace std;
8
9
class CMyClass
10

{
11
public:
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
50
private:
51
string objName;
52
};
53
54
#endif // __MYCLASS_H__
三、添加頭文件ExportFunc.h 內(nèi)容如下:
1
#ifndef __EXPORTFUNC_H__
2
#define __EXPORTFUNC_H__
3
4
#include "MyClass.h"
5
6
bool CreateObj(char *name);
7
bool DeleteObj();
8
void OperateObj();
9
bool CreateString(char *&pStr, int &size);
10
bool FressString(char *&pStr);
11
12
#endif // __EXPORTFUNC_H__
13
14
四、添加源文件ExportFunc.cpp 內(nèi)容如下:
15
16
#include "stdafx.h"
17
#include "ExportFunc.h"
18
19
CMyClass *pObj = NULL;
20
21
bool CreateObj(char *name)
22

{
23
DeleteObj();
24
pObj = new CMyClass(string(name));
25
return true;
26
}
27
28
bool DeleteObj()
29

{
30
if (pObj != NULL)
31
{
32
delete pObj;
33
pObj = NULL;
34
}
35
return true;
36
}
37
38
void OperateObj()
39

{
40
if (pObj == NULL)
41
{
42
return ;
43
}
44
pObj->PrintName();
45
}
46
47
bool CreateString(char *&pStr, int &size)
48

{
49
if (pObj == NULL)
50
{
51
return false;
52
}
53
return pObj->MallocString(pStr, size);
54
}
55
56
bool FressString(char *&pStr)
57

{
58
if (pObj == NULL)
59
{
60
return false;
61
}
62
return pObj->FreeString(pStr);
63
}
四、添加模塊定義文件CppDll.def 內(nèi)容如下:
1
LIBRARY "CppDll"
2
EXPORTS
3
CreateObj
4
DeleteObj
5
OperateObj
6
CreateString
7
FressString
五、在項目屬性設(shè)置默認(rèn)
六、在解決方案unlearn中添加一個C#的控制臺應(yīng)用程序項目CSApp
七、項目屬性->生成->輸出路徑改為"..\debug\" (其實就是讓兩個項目的輸出結(jié)果放在一個地方,debug版本C++工程默認(rèn)的輸出路徑是這個)
八、修改Program.cs文件 內(nèi)容如下:
1
using System.Runtime.InteropServices;
2
3
namespace 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設(shè)為啟動工程就可以了。這個例子很簡單,C#只是簡單調(diào)用了DLL中的幾個導(dǎo)出的接口函數(shù),它們其實沒有做什么,就有CreateObj和DeleteObj很重要,其它的函數(shù)只是簡單的把CMyClass的公共成員函數(shù)包了一下。這樣子就可以用C#使用C++所寫的類了,我們核心的代碼還是用面向?qū)ο蟮姆椒▉韺崿F(xiàn)的,而且本質(zhì)上我們是用了對象來幫助我們做事的。
當(dāng)然可能本人見識不夠,不知道還有更好的辦法,現(xiàn)在我也是剛剛想到這些的,好多都可以完善。最后還是一句話,我永遠(yuǎn)喜歡C++,我相信C++可以做得更好、更出色,不想看到亂用C++的事情出現(xiàn);有些人亂用了C++,還說C++一大堆的壞話。真正大型的工程其實C++才是最適合的。