page contents

C#调用C++动态库

本文讲述了C#调用C++动态库!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2022-10-mBWNfjX863461fb9bbf69.png本文讲述了C#调用C++动态库!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

C#调用C++的动态库方式有两种:

一种是直接调用:

这种形式可以用一个类来封装从dll文件中提取出来的方法,然后继承或调用此类;

using System.Runtime.InteropServices;//需要引入的命名空间

//前缀必须是static extern

[DllImport("dll文件完整路径", EntryPoint = "dll中封装的函数名"))]

public static extern Int GetInt(int ParameterInt);

//注意数据类型,

//      函数原型返回值为char*时,用IntPtr接受,并调用Marshal.PtrToStringAnsi()转为string

//      函数原型参数为char*时,用string类型传入

[DllImport("dll文件完整路径", EntryPoint = "dll中封装的函数名")]

public static extern IntPtr GetCharPoint(string ParameterCharPoint);

 

string str = Marshal.PtrToStringAnsi(init);//参数为IntPtr类型

另一种是动态调用:

这种方法更加灵活

        首先需要从kernel132.dll中静态调用出以下方法,之后会使用这几个方法来操作dll文件


//加载DLL

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

protected extern static IntPtr LoadLibrary(string path);

//获取函数地址

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

protected extern static IntPtr GetProcAddress(IntPtr lib, string funcName);

//释放相应的库

[DllImport("kernel32.dll")]

protected extern static bool FreeLibrary(IntPtr lib)

//获取错误信息

[DllImport("Kernel32.dll")]

public extern static int FormatMessage(int flag, ref IntPtr source, int msgid, int langid, ref string buf, int size, ref IntPtr args);

        使用这些方法来解析dll文件

    //此处的T指代一个函数委托的具体类型    

    T GetDelegate() 

        {

            //解析dll文件句柄

            IntPtr DllHandle = LoadLibrary("dll文件路径");

 

            //_获取函数指针

            IntPtr funcPoint = GetProcAddress(DllHandle, "dll中封装的方法名");

 

            //解析函数指针并转化为函数委托,并作为返回值.

            return (T)(object)Marshal.GetDelegateForFunctionPointer(funcPoint, typeof(T));

        }

然后就可以把dll中的方法作为这个委托函数来使用了

关于C#调用C++的参数问题:函数指针和回调函数部分:

在cpp端参数为一个函数指针时,在c#端以IntPtr类型作为参数;

实例化一个Delegate函数委托作为回调函数,调用Marshal.GetFunctionPointerForDelegate(此参数为该Delegate实例对象)转化为一个IntPtr类型函数指针,即可作为参数传入;

需要传入c++中定义为NULL的参数时,使用default(IntPtr)作为空指针;

cpp端的代码声明:

typedef bool (*FileStdCall)(const char* _FilePath);//_对文件的回调函数指针类型

typedef bool (*DirStdCall)(const char* _Directory);//_对文件夹的回调函数指针类型

extern "C" _declspec(dllexport)

void ErgodicDirAndFile(char* _BeginPath= NULL,

   DirStdCall _DirCall= NULL,

   FileStdCall _FileCall = NULL,

   bool _ifOnlyFirstDeep = false);

c#端的代码调用


public delegate void Api_Ergodic(string path, IntPtr dirCall, IntPtr fileCall, bool ifOneDeep);

public delegate bool Api_FileCall(string FilePath);

            //File 回调

            Api_FileCall api_FileCall = delegate (string path)

            {

                Console.WriteLine(path);

                return true;

            };

            //Ergodic函数

//GetFuncAsDelegate<T>是自己写的一个函数,作用是从dll文件中提取函数封装为T类型返回,失败时返回default

            Api_Ergodic api_Ergodic = GetFuncAsDelegate<Api_Ergodic>("ErgodicDirAndFile");

            if(api_Ergodic == default) {

                Console.WriteLine("api_Ergodic Failed");

            }else

            {

                api_Ergodic(dirPath,default(IntPtr),Marshal.GetFunctionPointerForDelegate(api_FileCall), false);

}

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

  • 发表于 2022-10-12 10:00
  • 阅读 ( 653 )
  • 分类:C/C++开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章