C#調(diào)用C++動態(tài)庫接口函數(shù)和回調(diào)函數(shù)方法
1. 前言
需求: 當(dāng)前C已經(jīng)寫好了一個動態(tài)庫,完成了產(chǎn)品開發(fā)需求,C#需要調(diào)用C編寫的動態(tài)庫DLL接口,開發(fā)出完整的軟件,DLL動態(tài)庫里包含了普通接口函數(shù),回調(diào)函數(shù)。
開發(fā)環(huán)境: win10 64位 、VS2017
2. 普通接口函數(shù)調(diào)用示例
2.1 C++端編寫接口
(1)頭文件里聲明需要提供的接口,導(dǎo)出接口,方便C#調(diào)用
//帶返回值無形參示例 EXTERN_C TOOLLIBRARY_API char* Version(void); //無返回值帶指針形參示例 EXTERN_C TOOLLIBRARY_API void SetApplicationDirPath(char *buff);
(2)源代碼
char* Version(void) { ?? ?return version_str; } void SetApplicationDirPath(char * buff) { ?? ?std::string str = buff; ?? ?printf("傳入的參數(shù):%s\n", buff); ?? ?std::cout << "字符串:"<<buff <<std::endl; }
這里寫了兩個函數(shù),分別演示傳參和帶返回值的接口函數(shù)使用方法。
2.2 C#端調(diào)用
namespace CSharp_LoadLibrary { ? ? class Program ? ? { ? ? ? ? [DllImport("TOOLLIBRARY.dll", EntryPoint = "Version", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] ? ? ? ? extern static IntPtr Version(); ? ? ? ? [DllImport("TOOLLIBRARY.dll", EntryPoint = "SetApplicationDirPath", CallingConvention = CallingConvention.Cdecl)] ? ? ? ? extern static void SetApplicationDirPath(IntPtr text); ? ? ? ?? ? ? ? ? static void Main(string[] args) ? ? ? ? { ? ? ? ? ? ? //傳入?yún)?shù)--測試 ? ? ? ? ? ? SetApplicationDirPath(Marshal.StringToHGlobalAnsi("傳入字符串測試..")); ? ? ? ? ? ? //打印返回值測試 ? ? ? ? ? ? Console.WriteLine(Marshal.PtrToStringAnsi(Version())); ? ? ? ? } ? ? } }
3. 回調(diào)函數(shù)調(diào)用示例
回調(diào)函數(shù),光聽名字就比普通函數(shù)要高大上一些,那到底什么是回調(diào)函數(shù)呢?下面來至百度百科的解釋:
回調(diào)函數(shù)就是一個通過函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個函數(shù),當(dāng)這個指針被用來調(diào)用其所指向的函數(shù)時(shí),我們就說這是回調(diào)函數(shù)。回調(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí)由另外的一方調(diào)用的,用于對該事件或條件進(jìn)行響應(yīng)。
回調(diào)函數(shù)是指 使用者自己定義一個函數(shù),實(shí)現(xiàn)這個函數(shù)的程序內(nèi)容,然后把這個函數(shù)(入口地址)作為參數(shù)傳入別人(或系統(tǒng))的函數(shù)中,由別人(或系統(tǒng))的函數(shù)在運(yùn)行時(shí)來調(diào)用的函數(shù)。函數(shù)是你實(shí)現(xiàn)的,但由別人(或系統(tǒng))的函數(shù)在運(yùn)行時(shí)通過參數(shù)傳遞的方式調(diào)用,這就是所謂的回調(diào)函數(shù)。簡單來說,就是由別人的函數(shù)運(yùn)行期間來回調(diào)你實(shí)現(xiàn)的函數(shù)。
3.1 C++端編寫接口
(1)頭文件聲明
//設(shè)置回調(diào)函數(shù)指針 EXTERN_C TOOLLIBRARY_API void Set_DebugCallBackFunction(void(*func)(const char *p));
(2)源代碼
//C++的回調(diào)函數(shù) void Set_DebugCallBackFunction(void(*func)(const char *p)) { ?? ?//設(shè)置回調(diào)函數(shù)指針 ?? ?CallBackFunction_p = func; ?? ?printf("回調(diào)函數(shù)設(shè)置成功.\n"); ?? ?CallBackFunction_p("這是回調(diào)函數(shù)傳出來的測試數(shù)據(jù).\n"); }
這是C端編寫的一個回調(diào)函數(shù)設(shè)置函數(shù),C#調(diào)用這個函數(shù)將函數(shù)指針傳遞過來,C通過傳遞過來的函數(shù)指針反過來主動調(diào)用C#的方法,實(shí)現(xiàn)數(shù)據(jù)交互。
3.2 C#端調(diào)用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; namespace CSharp_LoadLibrary { ? ? class Program ? ? { ? ? ? ? [DllImport("TOOLLIBRARY.dll", EntryPoint = "Set_DebugCallBackFunction", CallingConvention = CallingConvention.Cdecl)] ? ? ? ? extern static int Set_DebugCallBackFunction(CallbackDelegate callback); ? ? ? ?? ? ? ? ? //定義委托 ? ? ? ? [UnmanagedFunctionPointer(CallingConvention.Cdecl)] ? ? ? ? public delegate void CallbackDelegate(IntPtr Path); ? ? ? ? //接收C++回調(diào)數(shù)據(jù) ? ? ? ? //當(dāng)C++調(diào)用傳遞過去的函數(shù)指針時(shí),就會執(zhí)行下面這個方法 ? ? ? ? static void CallBackFunction(IntPtr Path) ? ? ? ? { ? ? ? ? ? ? Console.WriteLine("C++傳出來的回調(diào):" + Marshal.PtrToStringAnsi(Path)); ? ? ? ? } ? ? ? ? static void Main(string[] args) ? ? ? ? { ? ? ? ? ? ? //調(diào)用C++設(shè)置回調(diào)函數(shù)的接口,將C#的函數(shù)地址傳遞過去 ? ? ? ? ? ? Set_DebugCallBackFunction(CallBackFunction); ? ? ? ? } ? ? } }
到此這篇關(guān)于C#調(diào)用C++動態(tài)庫接口函數(shù)和回調(diào)函數(shù)方法的文章就介紹到這了,更多相關(guān)C#調(diào)用C++接口函數(shù)和回調(diào)函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#使用泛型方法設(shè)計(jì)實(shí)現(xiàn)單向鏈表詳解
這篇文章主要為大家詳細(xì)介紹了C#如何使用泛型方法設(shè)計(jì)實(shí)現(xiàn)一個單向鏈表,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02Quartz.Net任務(wù)和觸發(fā)器實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Quartz.Net任務(wù)和觸發(fā)器實(shí)現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12Unity3D使用Shader實(shí)現(xiàn)腐蝕消失
這篇文章主要為大家詳細(xì)介紹了Unity3D使用Shader實(shí)現(xiàn)腐蝕消失,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02