欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#與C++動(dòng)態(tài)鏈接庫(kù)DLL參數(shù)互傳方式

 更新時(shí)間:2022年11月08日 09:08:00   作者:weixin_46846685  
這篇文章主要介紹了C#與C++動(dòng)態(tài)鏈接庫(kù)DLL參數(shù)互傳方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、C#中導(dǎo)入C++動(dòng)態(tài)鏈接庫(kù)

從界面程序開(kāi)發(fā)的角度來(lái)說(shuō),C#語(yǔ)言效率較C++高,且通過(guò)WPF開(kāi)發(fā)出的程序界面更為美觀,但在開(kāi)發(fā)實(shí)際項(xiàng)目中有時(shí)不可避免的需要使用C++程序庫(kù),通常的做法是將C++程序編譯為動(dòng)態(tài)鏈接庫(kù),及DLL文件,然后在C#中進(jìn)行導(dǎo)入調(diào)用。

導(dǎo)出C++程序通常的做法是使用_declspec(dllexport) /_declspec(dllimport)來(lái)導(dǎo)入導(dǎo)出,C++示例代碼如下:

#include <iostream>
using namespace std;
extern "C" _declspec(dllexport) void TestDll(char* Path, char* result);
_declspec(dllexport) void TestDll(char* Path, char* result)
{
***//函數(shù)功能具體實(shí)現(xiàn)
}

以VS2019中編譯Dll為例,打開(kāi)項(xiàng)目屬性窗口,點(diǎn)擊配置屬性——常規(guī),將配置類型選擇為動(dòng)態(tài)庫(kù)(.dll),然后點(diǎn)擊配置屬性——高級(jí),將目標(biāo)文件擴(kuò)展名選擇為.dll,然后設(shè)置好解決方案配置和平臺(tái)后生成dll文件。

導(dǎo)出為Dll文件后,例如導(dǎo)出文件名為TestDll.dll,在C#中調(diào)用示例代碼如下:

[DllImport("TestDll.dll", EntryPoint = "TestDll")]
static extern void TestDll(string Path, [Out, MarshalAs(UnmanagedType.LPArray)] char[] result);

下面具體講如何在C#與C++之間實(shí)現(xiàn)參數(shù)傳遞。

二、C#傳入字符串參數(shù)

參數(shù)傳遞主要涉及C#調(diào)用dll文件時(shí)傳入dll參數(shù)和調(diào)用結(jié)束dll文件傳出參數(shù)。通常傳入dll的參數(shù)類型為整數(shù)類型,整數(shù)數(shù)組類型和字符串類型。

在C#和C++中整數(shù)類型通常都為int類型,在參數(shù)傳入時(shí)直接傳入即可。

但對(duì)于字符串類型,C#中為string類型,而C++中通常是使用字符數(shù)組來(lái)存儲(chǔ)字符串,即char[]或char*類型,而C++中也使用std::string類型來(lái)存儲(chǔ)字符串,但在實(shí)際使用過(guò)程中發(fā)現(xiàn)當(dāng)C++中接收參數(shù)類型是該類型時(shí)會(huì)報(bào)出錯(cuò)誤,

示例代碼如下:

//C++代碼
#include <iostream>
using namespace std;
extern "C" _declspec(dllexport) void TestDll(char* Path);
_declspec(dllexport) void TestDll(char* Path)
{
***//函數(shù)功能具體實(shí)現(xiàn)
}
//C#代碼
[DllImport("TestDll.dll", EntryPoint = "TestDll")]
static extern void TestDll(string Path);
string path = "hello";
TestDll(path);

上述代碼中,C#傳入字符串類型為string類型,而C++接收參數(shù)類型為char*類型,經(jīng)實(shí)際測(cè)試,中文字符和英文字符都可以正確傳輸。

三、C++傳出字符串參數(shù)

C++傳出字符串參數(shù)較C#傳入更為復(fù)雜,因C++中字符存儲(chǔ)是以指針形式,所以可以通過(guò)如下方式來(lái)實(shí)現(xiàn):C#傳入一個(gè)數(shù)組參數(shù),傳入后C++對(duì)該數(shù)組指針進(jìn)行賦值,然后傳出。

實(shí)現(xiàn)方式有兩種,一種為C#傳入char數(shù)組類型,一種為C#傳入byte數(shù)組類型,示例代碼如下:

//C++代碼
#include <iostream>
using namespace std;
extern "C" _declspec(dllexport) void TestDll(char* result);
_declspec(dllexport) void TestDll(char* result)
{
char s[20]="hello";
memcpy(result, s, strlen(s));
}

memcpy為C++內(nèi)存拷貝函數(shù),使用時(shí)需要注意strlen與sizeof函數(shù)的區(qū)別,兩者都是獲得變量的字節(jié)數(shù),不同的是strlen只適用于char*類型,當(dāng)遇到’\0’字節(jié)時(shí)停止計(jì)數(shù),而sizeof適用于多種類型和對(duì)象,當(dāng)用于數(shù)組類型時(shí)獲得的時(shí)初始化時(shí)分配的字節(jié)數(shù),而不是實(shí)際使用的字節(jié)數(shù)。

//C#代碼
[DllImport("TestDll.dll", EntryPoint = "TestDll")]
static extern void TestDll([Out, MarshalAs(UnmanagedType.LPArray)] char[] result);
char[] result = new char[100];
TestDll(result);
string re = new string(result);
Console.WriteLine(re);

在C#中傳入char[]即字符數(shù)組類型,待C++中對(duì)result賦值完成后再取出result,對(duì)字符串re賦值,這樣就實(shí)現(xiàn)了C++字符串參數(shù)的傳出。

需要注意的是在C#中數(shù)組是直接使用的,而在C++中返回的是數(shù)組的指針,[Out, MarshalAs(UnmanagedType.LPArray)]用來(lái)轉(zhuǎn)化這兩種不同的類型。

上述實(shí)現(xiàn)方式為傳入char數(shù)組類型方式,但如果C++傳出的字符串包含中文字符,那么可能在C#中會(huì)顯示亂碼,因?yàn)橹形淖址麨閁TF-8編碼。

下面介紹使用byte數(shù)組方式,C++中代碼不變,C#中代碼如下:

//C#代碼
[DllImport("TestDll.dll", EntryPoint = "TestDll")]
static extern void TestDll(ref byte t);
byte[] t = new byte[100];
TestDll(path, ref t[0]);
string re = Encoding.UTF8.GetString(t);
Console.WriteLine(re);

byte數(shù)組方式傳輸中文字符不算出現(xiàn)亂碼情況。

四、C++傳出vector<char*>參數(shù)

vector類型為C++中類似于列表的數(shù)據(jù)類型,能夠自由添加、插入、刪除元素,與C#中List類型功能相似。

但當(dāng)要在C++傳出vector類型時(shí),在C#端的接收數(shù)據(jù)類型卻不能為L(zhǎng)ist,否則會(huì)報(bào)出錯(cuò)誤,而應(yīng)該使用C#中的IntPtr類型,示例代碼如下:

//C++代碼
#include <iostream>
using namespace std;
extern "C" _declspec(dllexport) void TestDll(int& num, char** &result);
_declspec(dllexport) void TestDll(int& num, char** &result)
{
std::vector<char*> res;
char* tmp = new char[5];
char s[20]="hello";
memcpy(tmp, s, strlen(s));
res.push_back(tmp);
num = 1;
result = res.data();
}

在上述C++代碼中主要通過(guò)res.data()函數(shù)實(shí)現(xiàn)將vector<char*>類型轉(zhuǎn)換為char**類型,從而方便C#端讀取,而num變量而表示vector類型的元素個(gè)數(shù),C#端代碼如下:

//C#代碼
[DllImport("TestDll.dll", EntryPoint = "TestDll")]
static unsafe extern void TestDll(ref int num, ref IntPtr t);
int num = 0;
IntPtr data = IntPtr.Zero;
TestDll(ref num, ref data);
for (int i = 0; i < num; ++i)
{
   int size = Marshal.SizeOf(typeof(IntPtr));
   IntPtr intPtr = Marshal.ReadIntPtr(data, size * i);
   string datastr = Marshal.PtrToStringAnsi(intPtr);
   Console.WriteLine(datastr);
}

C#代碼中根據(jù)num個(gè)數(shù)依次從內(nèi)存中讀取字符串,從內(nèi)存中讀取字符串函數(shù)為Marshal.PtrToStringAnsi(intPtr),需要注意的是如果C++傳出的包含中文字符,那么在C#端可能顯示亂碼。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Unity中的Tilemap流程分析

    Unity中的Tilemap流程分析

    這篇文章給大家介紹Unity中的Tilemap流程分析,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-07-07
  • Js中的substring,substr與C#中的Substring比較

    Js中的substring,substr與C#中的Substring比較

    本篇文章主要是對(duì)Js中的substring,substr與C#中的Substring進(jìn)行了比較。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2014-01-01
  • C#檢查foreach判讀是否為null的方法

    C#檢查foreach判讀是否為null的方法

    這篇文章主要介紹了C#如何檢查foreach判讀其是否為null,文中給出了示例代碼,介紹的很詳細(xì),需要的朋友可以參考下方法
    2016-09-09
  • C#編程實(shí)現(xiàn)Excel文檔中搜索文本內(nèi)容的方法及思路

    C#編程實(shí)現(xiàn)Excel文檔中搜索文本內(nèi)容的方法及思路

    有了在Word文檔中編程實(shí)現(xiàn)搜索文本的經(jīng)驗(yàn),在Excel中實(shí)現(xiàn)這個(gè)功能也并非難事。
    2013-07-07
  • C#實(shí)現(xiàn)窗體全屏的兩種方法

    C#實(shí)現(xiàn)窗體全屏的兩種方法

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)窗體全屏的兩種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • C#生成exe并用process運(yùn)行的流程步驟

    C#生成exe并用process運(yùn)行的流程步驟

    這篇文章主要介紹了C#生成exe并用process運(yùn)行的流程步驟,文中通過(guò)代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-08-08
  • C#版Tesseract庫(kù)的使用技巧

    C#版Tesseract庫(kù)的使用技巧

    本文給大家分享C#版Tesseract庫(kù)的使用技巧,在這里大家需要注意一下tesseract的識(shí)別語(yǔ)言包要自己下載后包含到項(xiàng)目里面,并設(shè)置為始終復(fù)制,或者直接把這個(gè)文件包放到運(yùn)行程序目錄(bin\debug)下的,具體實(shí)現(xiàn)代碼跟隨小編一起學(xué)習(xí)下吧
    2021-05-05
  • 詳解C# 虛方法virtual

    詳解C# 虛方法virtual

    這篇文章主要介紹了C# 虛方法virtual的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-04-04
  • Unity Shader實(shí)現(xiàn)紋理遮罩效果

    Unity Shader實(shí)現(xiàn)紋理遮罩效果

    這篇文章主要為大家詳細(xì)介紹了Unity Shader實(shí)現(xiàn)紋理遮罩效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C# 泛型數(shù)組學(xué)習(xí)小結(jié)

    C# 泛型數(shù)組學(xué)習(xí)小結(jié)

    C# 泛型數(shù)組學(xué)習(xí)中我們需要注意什么事項(xiàng)呢?C# 泛型數(shù)組的使用又是如何呢?那么本文就向你詳細(xì)介紹這方面的內(nèi)容
    2012-09-09

最新評(píng)論