久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

如何在C#中調(diào)用C++方法

 風(fēng)聲之家 2021-10-26
原創(chuàng)  列位一分鐘 2021-10-24

收錄于話題

#c#4
#.net3
#平臺(tái)調(diào)用1
#互操作1
#C++1

主要方式

C#主要通過兩種方式提供對非托管代碼的調(diào)用,,第一種是使用平臺(tái)調(diào)用(Platform Invoke,,P/Invoke),第二種是使用不安全代碼(unsafe),,日常開發(fā)中我們使用最多的就是第一種,,所以下面我們來介紹下如何使用平臺(tái)調(diào)用。

平臺(tái)調(diào)用

CLI通過P/Invoke提供該功能,,它允許對非托管DLL所導(dǎo)出的函數(shù)執(zhí)行API調(diào)用,。平臺(tái)調(diào)用主要有這些步驟:聲明外部函數(shù)、映射數(shù)據(jù)類型、錯(cuò)誤處理,。

1. 聲明外部函數(shù)

和類的所有普通方法一樣,,我們需要在類的上下文中聲明目標(biāo)API,同時(shí)為它添加extern修飾符,,從而把它聲明為外部函數(shù),。它幾乎總是靜態(tài)的(static)。如下代碼所示,,我們聲明了外部函數(shù)SendMessage(位于user32.dll中),,EntryPoint屬性可以省略不寫,也可以指定一個(gè)函數(shù)名用來覆蓋默認(rèn)的行為,,CharSet屬性則用于指定調(diào)用API的Unicode還是ASCII版本或者由.NET平臺(tái)自動(dòng)嘗試調(diào)用,。

using System;
using System.Runtime.InteropServices;

namespace PayPlatformProxy
{
    public class LevyTest
    {
        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
    }
}
2. 數(shù)據(jù)類型映射
  • 托管代碼的基元類型不會(huì)隨處理器改變大小,無論是32位還是64位處理器,,int類型始終是32位,,但在非托管代碼中,內(nèi)存指針會(huì)隨處理器而變化,。因此,,C++中的HANDLE和LPVOID等類型不能對應(yīng)為int,而應(yīng)該對應(yīng)為IntPtr,,其大小隨處理器內(nèi)存布局而變化,。
  • 微軟官網(wǎng)文檔--類型封送有涉及類型的映射,大家可以參考學(xué)習(xí)下,。另外,,pinvoke.net中也有很多系統(tǒng)API在C#中的聲明示例,輸入關(guān)鍵字看看示例是如何映射,,從而完成非托管類型到托管類型的映射,。
  • 此外,通過工具pinvoke-interop-assistant也可以來生成C++方法在C#中對應(yīng)的簽名,,實(shí)例演示部分我們將使用此工具,。

實(shí)例演示

如下我們定義了C++的方法LevyAgeAdd,它的目的是輸入姓名和年齡然后返回新的年齡(newAge)和提示年齡增長的信息(resultMsg),。

extern "C"
{
   _declspec(dllexport) void LevyAgeAdd(const char* name, int age, int* newAge, char* resultMsg);
}

下面我們在pinvoke-interop-assistant工具中輸入C++方法的聲明,,然后點(diǎn)擊Generate就能生成對應(yīng)的C#方法的簽名了,如下圖所示圖片

接著我們通過C#代碼來調(diào)用此C++代碼,,首先拷貝出外部函數(shù)LevyAgeAdd的聲明,,然后調(diào)用方法傳入各個(gè)參數(shù)值,如下:

[DllImport("Project1.dll", EntryPoint="LevyAgeAdd", CharSet = CharSet.Auto)]
public static extern void LevyAgeAdd([In()][MarshalAs(UnmanagedType.LPStr)] string name, int age, ref int newAge, IntPtr resultMsg);

void Main()
{
 int newAge = 0;
 IntPtr p = Marshal.AllocHGlobal(255);
 //調(diào)用C++方法
 LevyAgeAdd("楊小豆"25ref newAge, p);
 string resultMsg = Marshal.PtrToStringAnsi(p);
 $"newAge的值: {newAge}".Dump();
 $"resultMsg的值: {resultMsg}".Dump();
}

輸出結(jié)果如下圖:圖片

哈哈,,調(diào)用結(jié)果正確,!真香,!事實(shí)上我們C++代碼的實(shí)現(xiàn)也確實(shí)是把年齡增加了3歲然后輸出提示信息的。希望本文能對童鞋們有所幫助,!

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多