Bootstrap

C#调用c++dll的两种方法(静态方法和动态方法)

一.c#项目创建

1.创建一个console控制台程序。

2.把dll拷贝到c#生成的.exe程序的目录内。

3.在c#的program.cs类引入命名空间System.Runtime.InteropServices。

  System.Runtime.InteropServices 命名空间提供了一系列类、接口和属性,主要用于促进托管代码(C# 代码)和非托管代码(如 C 或 C++ 代码)之间的互操作性。

它允许 C# 程序与 Windows API、动态链接库(DLL)、COM 组件等进行交互,使开发人员能够在 C# 程序中调用非托管代码,以及对 COM 组件进行操作。

二.调用c++ DLL方法一(静态调用)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.InteropServices;

using System.Text;

using System.Threading.Tasks;

namespace ConsoleApp3

{

    class Program

    {

        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]

        extern static int add(int a, int b);

        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]

        extern static int minus(int a, int b);

        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]

        extern static IntPtr Getversion();

        

        static void Main(string[] args)

        {

            Console.WriteLine(add(1,6));

            Console.WriteLine(minus(1, 6));

            IntPtr pStr = Getversion();

            string version = Marshal.PtrToStringAnsi(pStr);

            Console.WriteLine(version);

            Console.ReadKey();

        }

    }

}

三.调用c++ DLL方法二(动态调用)

这样做的好处是,dll不用放到exe的根目录,可以自己放到任何地方,方便管理。

1.新建一个DLLWrapper类。

代码如下:

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Runtime.InteropServices;

using System.Text;

using System.Threading.Tasks;

namespace ConsoleApp3

{

    public class DLLWrapper

    {

        [DllImport("kernel32.dll", SetLastError = true)]

        static extern IntPtr LoadLibrary(string lpFileName);

        [DllImport("kernel32.dll", SetLastError = true)]

        static extern bool FreeLibrary(IntPtr hModule);

        [DllImport("kernel32.dll", SetLastError = true)]

        static extern bool SetDllDirectory(string lpPathName);

        IntPtr pDll = IntPtr.Zero;

        public bool LoadDynamicLibrary(string path,string dlname)

        {

            if (File.Exists(Path.Combine(path, dlname)))

            {

                SetDllDirectory(path);

                pDll = LoadLibrary(dlname);

                if (pDll == IntPtr.Zero)

                {

                    Console.WriteLine("Failed to load DLL");

                    return false;

                }

                else

                {

                    Console.WriteLine("load DLL success");

                    return true;

                }

            }

            else

            {

                Console.WriteLine("DLL is not exist");

                return false;

            }

        }

        public bool FreeDllIntPtr()

        {

            bool resultFree = FreeLibrary(pDll);

            if (resultFree)

            {

                Console.WriteLine("DLL successfully unloaded.");

                return true;

            }

            else

            {

                Console.WriteLine("Failed to unload DLL.");

                return false;

            }

        }

    }

}

2.在program.cs调用这个类

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.InteropServices;

using System.Text;

using System.Threading.Tasks;

namespace ConsoleApp3

{

    class Program

{

[DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]

        extern static int add(int a, int b);

        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]

        extern static int minus(int a, int b);

        [DllImport("Testdll.dll", CallingConvention = CallingConvention.Cdecl)]

        extern static IntPtr Getversion();

        static void Main(string[] args)

        {

            DLLWrapper Wrapper = new DLLWrapper();

            //加载dll,传入dll的文件夹路径

            Wrapper.LoadDynamicLibrary(Environment.CurrentDirectory+ "\\Library", "Testdll.dll");

            Console.WriteLine(add(1,5));

            Console.WriteLine(minus(1, 5));

            IntPtr pStr = Getversion();

            string version = Marshal.PtrToStringAnsi(pStr);

            Console.WriteLine(version);

            //释放dll

            Wrapper.FreeDllIntPtr();

            Console.ReadKey();

        }

    }

}

;