因爲歷史緣由,不少時候咱們的代碼並不徹底是使用.NET寫成的。這時候和以往C++代碼的混合編程就顯得至關重要了。最近碰到了這樣的問題,將方法簡要記述以下。編程
調用簡單的C++函數
要在C#代碼中調用C++函數,大致的思路是這樣的:首先將C++函數寫成DLL形式的庫,而後在C#中導入DLL中的函數進行調用。具體的代碼相似這樣:
C++代碼:數組
1
int
StaticElementNumber
=
10
;
2
extern
"
C
"
AFX_API_EXPORT
int
GetArrayElementNumber()
3
{
4
return
StaticElementNumber;
5
}
C#代碼:
(導入函數部分,寫在調用函數所在類中)函數
1
[DllImport(
"
MFCDll.dll
"
)]
2
public
static
extern
int
GetArrayElementNumber();
3
int
ElementNumber
=
GetArrayElementNumber();
s其中的細節,好比int和char等數據類型在C++和C#中佔用的空間不一樣等等CLR會自動處理。(主要是經過Marshal類自動處理)post
這樣的調用還支持調試。打開C#工程的Properties,在Debug選項卡中勾選Enable unmanaged code debugging便可啓用C++代碼調試。這樣在調試模式下,調用這個函數時能夠繼續按F11跟進函數內部進行調試。spa
傳遞GDI對象
一些複雜的Windows對象能夠經過句柄來傳送。好比下面的代碼就將一個GDI+ Bitmap對象轉換成GDI句柄進行傳送。
C++代碼(GDI+的聲明,引用等等省略):debug
1
extern
"
C
"
AFX_API_EXPORT HBITMAP GetABitmap(WCHAR
*
strFileName)
2
{
3
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
4
ULONG_PTR gdiplusToken;
5
GdiplusStartup(
&
gdiplusToken,
&
gdiplusStartupInput, NULL);
6
Bitmap
*
bitmap
=
Bitmap::FromFile(strFileName);
7
HBITMAP HBitmapToReturn;
8
bitmap
->
GetHBITMAP(NULL,
&
HBitmapToReturn);
9
GdiplusShutdown(gdiplusToken);
10
11
return
HBitmapToReturn;
12
}
C#代碼(用戶界面採用WPF,略去相關聲明和引用):調試
1
[DllImport(
"
MFCDll.dll
"
)]
2
public
static
extern
IntPtr GetABitmap([MarshalAs(UnmanagedType.LPWStr)]
string
strFileName);
3
4
private
void
MenuItemFileOpenOnClicked(
object
sender, RoutedEventArgs e)
5
{
6
OpenFileDialog dialog
=
new
OpenFileDialog();
7
dialog.Title
=
"
Load an image...
"
;
8
dialog.Multiselect
=
false
;
9
if
(dialog.ShowDialog()
==
true
)
10
{
11
mainGrid.Children.Clear();
12
13
IntPtr hBitmap
=
GetABitmap(dialog.FileName);
14
Bitmap bitmap
=
Bitmap.FromHbitmap(hBitmap);
15
System.Windows.Controls.Image image
=
new
Windows.Controls.Image();
16
image.Source
=
Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, ro, Int32Rect.Empty,
17
Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
18
image.Stretch
=
System.Windows.Media.Stretch.Fill;
19
DeleteObject(hBitmap);
20
mainGrid.Children.Add(image);
21
}
22
}
傳遞數組
傳遞定長數組很簡單,此處不述。下面的代碼實現變長數組的傳遞:
C++代碼:code
1
int
StaticElementNumber
=
10
;
2
extern
"
C
"
AFX_API_EXPORT
bool
GetArray(
int
ElementNumber,
double
*
BaseAddress)
3
{
4
if
(ElementNumber
<
StaticElementNumber)
5
{
6
return
false
;
7
}
8
9
for
(
int
i
=
0
; i
<
StaticElementNumber;
++
i)
10
{
11
BaseAddress[i]
=
1
/
((
double
)i
+
1
);
12
}
13
14
return
true
;
15
}
16
17
extern
"
C
"
AFX_API_EXPORT
int
GetArrayElementNumber()
18
{
19
return
StaticElementNumber;
20
}
C#代碼: 對象
1
[DllImport(
"
MFCDll.dll
"
)]
2
public
static
extern
bool
GetArray(
int
ElementNumber, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex
=
0
)]
double
[] BaseAddress);
3
4
private
void
MenuItemFileGetArrayOnClicked(
object
sender, RoutedEventArgs e)
5
{
6
//
Get array data.
7
int
ElementNumber
=
GetArrayElementNumber();
8
double
[] doubleArray
=
new
double
[ElementNumber];
9
GetArray(ElementNumber, doubleArray);
10
11
//
Show the data.
12
mainGrid.Children.Clear();
13
ListBox listBox
=
new
ListBox();
14
foreach
(
double
number
in
doubleArray)
15
{
16
listBox.Items.Add(number);
17
}
18
mainGrid.Children.Add(listBox);
19
}
20
有了這三個功能,通常來講C++代碼複用到C#平臺上就是比較簡單的事情了。blog