title: 'C#調用C++ dll編寫的程序'
date: 2016-04-10 18:37:16
tags: C#
categories: c#
編寫c dll
- 創(chuàng)建一個win32程序如孝,選擇DLL
- 新建一個.h 文件比如 CDLL.h
- 創(chuàng)建一個.cpp文件 CDLL.cpp
extern "C" _declspec(dllexport) int Add(int x, int y)
{
return x + y;
}
extern "C" _declspec(dllexport) int Sub(int x, int y)
{
return x - y;
}
- 在.h 文件對函數(shù)進行申明
- 在.cpp文件里對文件定義
extern "C" 包含雙重含義欺矫,從字面上即可得到:首先分预,被它修飾的目標>是“extern”的;其次诈皿,被它修飾的目標是“C”的。而被extern "C"修飾 >的變量和函數(shù)是按照C語言方式編譯和連接的管宵。
__declspec(dllexport)的目的是為了將對應的函數(shù)放入到DLL動態(tài)庫中前痘。 extern "C" __declspec(dllexport)加起來的目的是為了使用DllImport調用非托管C++的DLL文件。因為使用DllImport只能調用由C語言函數(shù)做成的DLL坎拐。
c#調用dll
- 將該dll放到c#文件目錄下
- 開始編寫代碼
[DllImport("Win32Project1.dll", EntryPoint = "Add", CharSet = CharSet.Auto,CallingConvention = CallingConvention.Cdecl)]
extern static int Add(int x, int y);
[DllImport("Win32Project1.dll", EntryPoint = "Sub", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
extern static int Sub(int x, int y);
static void Main(string[] args)
{
Console.WriteLine(Add(10, 2).ToString());
Console.WriteLine(Sub(10, 2).ToString());
Console.Read();
}
dllimport 調用該dll, EntryPoint 調用函數(shù)的名字烦磁,CharSet 字符編碼,
CharSet屬性是用來確定在托管與非托管調用的過程中用什么字符編碼來封送數(shù)據(jù),因為我們的.NET平臺是采用的Unicode編碼哼勇,而標準C++是采用的Ansi編碼都伪,在我們了解了非托管代碼的編碼方式之后,我們就很確定用什么編碼积担,那么如果我們不清楚非托管代碼是用什么語言編寫的或者不清楚它的編碼方式時陨晶,我們可以使用CharSet枚舉中的auto值,讓CLR自動為我們處理相關細節(jié)帝璧;
DllImport特性中的CallingConvention可選屬性先誉;
CallingConvention屬性也是一個比較重要的屬性,在平臺調用的過程中起到查找入口點的作用的烁,在托管代碼進行非托管代碼入口點查找時褐耳,會通過CallingConvention中的值進行確認非托管入口點的調用約定,上篇文章中我們提到了調用約定的一些概念撮躁,
tips
我在寫好代碼后報錯漱病,在百度一番后知道是x86的dll在64位的程序里調用會出問題,所以我調整了Any cpu 為x86.然后可以正常運行了.