1.C/C++动态库的编写
下面是我编写的一个比较简单的C++dll文件用来测试,关于如何编写dll文件,我这里便不再赘述,不懂得自行查询,
(1).h文件
#ifdef MYDLL_EXPORTS #define MYDLL_API __declspec(dllexport) #else #define MYDLL_API __declspec(dllimport) #endif//求两个整数的和(普通类型的参数) extern "C" MYDLL_API int GetSum(int nNum1, int nNum2); //获取两个整数中的最大值(含有整数类型的指针为参数) extern "C" MYDLL_API int GetMaxValue(int *pValue1, int* pValue2); //获取两个整数中的最小值,最小值以传出参数获取 extern "C" MYDLL_API void GetMinValue(int *pValue1, int* pValue2, int *pMinValue); //带有char[]与char*参数 extern "C" MYDLL_API int GetLength(char szName[64], char* szBirth);
(2).cpp文件
//求两个整数的和(普通类型的参数) extern "C" MYDLL_API int GetSum(int nNum1, int nNum2) { return (nNum1 + nNum2); } //获取整个整数中的最大值 extern "C" MYDLL_API int GetMaxValue(int *pValue1, int* pValue2) { return (*pValue1 > *pValue2) ? *pValue1 : *pValue2; } //获取两个整数中的最小值,最小值以传出参数获取 extern "C" MYDLL_API void GetMinValue(int *pValue1, int* pValue2, int *pMinValue) { if (*pValue1 < *pValue2) { *pMinValue = *pValue1; } else { *pMinValue = *pValue2; } } //带有char[]与char*参数 extern "C" MYDLL_API int GetLength(char szName[64], char* szBirth) { return (strlen(szName) + strlen(szBirth)); }
2.在C#项目中封装上述库文件为C#接口
上述库文件编译成功后,需要把它拷贝到C#项目的运行目录下,然后代码中使用using System.Runtime.InteropService命名空间即可引用
如果不想直接拷贝,可在C#项目中建立一个文件夹,如名称为Dll,将上述库文件拷贝到此文件夹,然后打开C#项目,点击项目->属性->生成事件中添加copy "$(SolutionDir)Dll\*.dll" "$(TargetDir)此批处理语句。程序编译成功后便会自行将此库文件拷贝到运行目录下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; namespace Dll_Test { public class MyDllHelper { private delegate void CallBackDelegate(int nValue1, int nValue2); //接口实现 public int GetMySum(int num1, int num2) { return (GetSum(num1, num2)); } public int GetMyMaxValue(IntPtr Value1, IntPtr Value2) { return GetMaxValue(Value1, Value2); } public void GetMyMinValue(IntPtr Value1, IntPtr Value2, ref int MinValue) { GetMinValue(Value1, Value2, ref MinValue); } public int GetMyLength(string strName, string strBirth) { return GetLength(strName, strBirth); } [DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)] private static extern int GetSum(int num1, int num2); [DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)] private static extern int GetMaxValue(IntPtr Value1, IntPtr pValue2); [DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void GetMinValue(IntPtr Value1, IntPtr Value2, ref int MinValue); [DllImport("MyDll.dll", CallingConvention =CallingConvention.Cdecl)] private static extern int GetLength(string strName, string strBirth); } }
3.接口实现
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Dll_Test { class Program { static void Main(string[] args) { MyDllHelper myDll = new MyDllHelper(); Console.WriteLine("两个整数和为:{0}", myDll.GetMySum(10, 10)); int nValue1 = 10; int nValue2 = 50; IntPtr ptr1 = Marshal.AllocHGlobal(sizeof(int)); IntPtr ptr2 = Marshal.AllocHGlobal(sizeof(int)); Marshal.WriteInt32(ptr1, nValue1); Marshal.WriteInt32(ptr2, nValue2); Console.WriteLine("两个整数中的最大值:{0}", myDll.GetMyMaxValue(ptr1, ptr2)); int nMinValue = 0; myDll.GetMyMinValue(ptr1, ptr2, ref nMinValue); Console.WriteLine("两个整数中最大值:{0}", nMinValue); Marshal.FreeHGlobal(ptr1); Marshal.FreeHGlobal(ptr2); string strName = "zhangsan"; string strBirth = "1993-01-01"; int nLength = myDll.GetMyLength(strName, strBirth); Console.WriteLine("两个字符串的总长度为:{0}", nLength); Console.ReadKey(); } } }