受欢迎的博客标签

call c++ dll or class within c# project :C# 中动态调用 两种类型的C++动态链接dll (非托管C++创建的dll库 CLR托管C++dll库)

Published

C#调用C++的dll有两种方案:

1、非托管C++创建的dll库,需要用静态方法调用;
2、直接使用CLR,生成托管C++dll库。

在项目中需要通过C++调用C#的dll,或者反过来调用。首先明白一个前提:

C#是托管型代码。
C++是非托管型代码。


托管型代码的对象在托管堆上分配内存,创建的对象由虚拟机托管。(C# )
非托管型代码对象有实际的内存地址,创建的对象必须自己来管理和释放。(C++)

本篇针对非托管C++创建的dll库的调用。

1.静态加载DLL库,声明函数的方式

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace InteropDemo
{
publicstaticclass NativeMethod
   {
       [DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
publicstaticexternint LoadLibrary(
           [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);

       [DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
publicstaticextern IntPtr GetProcAddress(int hModule,
           [MarshalAs(UnmanagedType.LPStr)] string lpProcName);

       [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
publicstaticexternbool FreeLibrary(int hModule);
   }
}

 

2. 2.动态加载DLL库的方式

使用NativeMethod类动态读取C++Dll,获得函数指针,并且将指针封装成C#中的委托。原因很简单,C#中已经不能使用指针了,如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace InteropDemo
{
class Program
   {
//[DllImport("CppDemo.dll", EntryPoint = "Add", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
//public static extern int Add(int a, int b); //DllImport请参照MSDN


staticvoid Main(string[] args)
       {
//1. 动态加载C++ Dll
int hModule = NativeMethod.LoadLibrary(@"c:\CppDemo.dll");
if (hModule == 0) return;

//2. 读取函数指针
           IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add");

//3. 将函数指针封装成委托
           Add addFunction = (Add)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(Add));

//4. 测试
           Console.WriteLine(addFunction(1, 2));
           Console.Read();
       }

///<summary>
/// 函数指针
///</summary>
///<param name="a"></param>
///<param name="b"></param>
///<returns></returns>
delegateint Add(int a, int b);

   }
}