溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

C#怎么調(diào)用C++動(dòng)態(tài)庫(kù)接口函數(shù)和回調(diào)函數(shù)

發(fā)布時(shí)間:2022-03-22 09:02:44 來(lái)源:億速云 閱讀:334 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“C#怎么調(diào)用C++動(dòng)態(tài)庫(kù)接口函數(shù)和回調(diào)函數(shù)”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“C#怎么調(diào)用C++動(dòng)態(tài)庫(kù)接口函數(shù)和回調(diào)函數(shù)”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

1. 前言

需求: 當(dāng)前C已經(jīng)寫(xiě)好了一個(gè)動(dòng)態(tài)庫(kù),完成了產(chǎn)品開(kāi)發(fā)需求,C#需要調(diào)用C編寫(xiě)的動(dòng)態(tài)庫(kù)DLL接口,開(kāi)發(fā)出完整的軟件,DLL動(dòng)態(tài)庫(kù)里包含了普通接口函數(shù),回調(diào)函數(shù)。

開(kāi)發(fā)環(huán)境: win10 64位 、VS2017

C#怎么調(diào)用C++動(dòng)態(tài)庫(kù)接口函數(shù)和回調(diào)函數(shù)

2. 普通接口函數(shù)調(diào)用示例

2.1 C++端編寫(xiě)接口

(1)頭文件里聲明需要提供的接口,導(dǎo)出接口,方便C#調(diào)用

//帶返回值無(wú)形參示例
EXTERN_C TOOLLIBRARY_API char* Version(void);
//無(wú)返回值帶指針形參示例
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;
}

這里寫(xiě)了兩個(gè)函數(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ù)--測(cè)試
            SetApplicationDirPath(Marshal.StringToHGlobalAnsi("傳入字符串測(cè)試.."));

            //打印返回值測(cè)試
            Console.WriteLine(Marshal.PtrToStringAnsi(Version()));
        }
    }
}

3. 回調(diào)函數(shù)調(diào)用示例

回調(diào)函數(shù),光聽(tīng)名字就比普通函數(shù)要高大上一些,那到底什么是回調(diào)函數(shù)呢?下面來(lái)至百度百科的解釋:

回調(diào)函數(shù)就是一個(gè)通過(guò)函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用來(lái)調(diào)用其所指向的函數(shù)時(shí),我們就說(shuō)這是回調(diào)函數(shù)。回調(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí)由另外的一方調(diào)用的,用于對(duì)該事件或條件進(jìn)行響應(yīng)。

回調(diào)函數(shù)是指 使用者自己定義一個(gè)函數(shù),實(shí)現(xiàn)這個(gè)函數(shù)的程序內(nèi)容,然后把這個(gè)函數(shù)(入口地址)作為參數(shù)傳入別人(或系統(tǒng))的函數(shù)中,由別人(或系統(tǒng))的函數(shù)在運(yùn)行時(shí)來(lái)調(diào)用的函數(shù)。函數(shù)是你實(shí)現(xiàn)的,但由別人(或系統(tǒng))的函數(shù)在運(yùn)行時(shí)通過(guò)參數(shù)傳遞的方式調(diào)用,這就是所謂的回調(diào)函數(shù)。簡(jiǎn)單來(lái)說(shuō),就是由別人的函數(shù)運(yùn)行期間來(lái)回調(diào)你實(shí)現(xiàn)的函數(shù)。

3.1 C++端編寫(xiě)接口

(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ù)傳出來(lái)的測(cè)試數(shù)據(jù).\n");
}

這是C端編寫(xiě)的一個(gè)回調(diào)函數(shù)設(shè)置函數(shù),C#調(diào)用這個(gè)函數(shù)將函數(shù)指針傳遞過(guò)來(lái),C通過(guò)傳遞過(guò)來(lái)的函數(shù)指針?lè)催^(guò)來(lái)主動(dòng)調(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)用傳遞過(guò)去的函數(shù)指針時(shí),就會(huì)執(zhí)行下面這個(gè)方法
        static void CallBackFunction(IntPtr Path)
        {
            Console.WriteLine("C++傳出來(lái)的回調(diào):" + Marshal.PtrToStringAnsi(Path));
        }

        static void Main(string[] args)
        {
            //調(diào)用C++設(shè)置回調(diào)函數(shù)的接口,將C#的函數(shù)地址傳遞過(guò)去
            Set_DebugCallBackFunction(CallBackFunction);
        }
    }
}

讀到這里,這篇“C#怎么調(diào)用C++動(dòng)態(tài)庫(kù)接口函數(shù)和回調(diào)函數(shù)”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI