網站首頁 編程語言 正文
C#與C++ dll之間傳遞字符串string wchar_t* char* IntPtr
1、由C#向C++ dll 傳入字符串時,參數直接用string,設置編碼格式 CharSet.Unicode CharSet.Ansi。
C++ dll接收使用wchar_t* 或 char*。
2、由C++ dll返回字符串,使用 wchar_t 或char*。
- .net 4.0 C#可以直接使用string接收,很方便。
- .net 4.0+ C# 用 IntPtr 接收,使用string接收調試不行。
dll代碼如下:
extern "C" _declspec(dllexport)const wchar_t* Diagnoser(wchar_t* inputText)
{
? ? delete diagnoser;
? ? diagnoser = new FireEye::Diagnoser();
? ? diagnoser->diagnose(inputText);
? ? diagnoser->report();
? ? return diagnoser->reportText.c_str();
}
C#代碼如下:
//聲明
[DllImport("FireEyeDll.dll", CharSet = CharSet.Unicode , CallingConvention = CallingConvention.Cdecl)]
//public static extern string Diagnoser(string inputText); //.net 4.0
public static extern IntPtr Diagnoser(string inputText);
?
?
?
//調用
//outputBox.Text = Diagnoser(inputBox.Text); //.net 4.0
IntPtr outPtr = Diagnoser(inputBox.Text);
outputBox.Text = Marshal.PtrToStringUni(outPtr);
C#調用C++ DLL的步驟以及遇到的亂碼等問題
C++ DLL動態庫Lib_LR.dll
函數聲明:
DLL_API_LR void GetAuthInfo(char* strCode);
函數定義:
兩個入參,兩個出參
void GetAuthInfo(int inPrama1, char *inParam2, int outParam1, char *outParam2)
{
? ? char buff[2048];
? ? memset(buff, 0, 2048);
? ? std::ifstream inFile("license.lr", std::ios::binary);
? ? if (inFile.fail())
? ? {
? ? ? ? return;
? ? }
? ? else
? ? {
? ? ? ? inFile.read(buff, sizeof(temp));
? ? ? ? inFile.close();
? ? }
? ? memcpy(outParam2, buff, outParam2.length());
? ? string strCode=outParam2;
? ? outParam1=strCode.length();
}
C#調用流程
函數引用:
[DllImport("Lib_LR.dll", EntryPoint = "GetAuthInfo", CallingConvention = CallingConvention.Cdecl)]
public static extern void GetAuthInfo(ref int InParam1, string nInPrama2, StringBuilder strCode);
函數調用:
int inParam1=0;
int outParam1=0;
string inParam2="測試";
StringBuilder outParam2= new StringBuilder(1024);
//注意:調用函數的時候,int型的出口參數要加ref,出口字符串參數要聲明StringBuilder類型
GetAuthInfo(inParam1,inParam2,ref outParam1,outParam2);
遇到的問題
1、平臺不匹配:
C#工程是基于.net core的webapi項目,默認編譯平臺選擇的是Any CPU,而C++ DLL工程默認的平臺是x86,這就產生了調用方(C#工程)和被調用方(DLL)編譯平臺不匹配的問題。可以嘗試通過以下方法來解決:C++ DLL和C#工程編譯的時候都選擇x86或者x64(前提操作系統是64位才行)。
2、亂碼問題:
調用GetAuthInfo函數的時候,獲取到的strCode出現亂碼,網上給出的解決方法是改變函數參數聲明方式public static extern voidGetAuthInfo([MarshalAs(UnmanagedType.LPStr)] StringBuilder strCode)。但是這種方法我試了,沒有效果。最后通過修改DLL源碼的方式得到解決:在GetAuthInfo函數的最后加上outParam2[strCode.length()] = '\0';這一行代碼,也就是在字符串數組末尾添加上結束符。
原文鏈接:https://blog.csdn.net/tinghe17/article/details/114381046tinghe17
相關推薦
- 2021-12-04 淺談C++中const與constexpr的區別_C 語言
- 2022-04-09 SpringMVC 基礎配置文件(簡潔版本)
- 2022-07-22 jQuery實現點擊顯示密碼框密碼
- 2023-01-26 RecyclerView?源碼淺析測量?布局?繪制?預布局_Android
- 2023-01-08 Go設計模式原型模式考查點及使用詳解_Golang
- 2022-02-13 上傳文件出現 413 Request Entity Too Large
- 2022-02-14 jquery-選擇器、篩選器、樣式操作、文本操作、屬性操作、文檔處理
- 2022-02-09 利用上下文屬性將?C++?對象嵌入?QML?里_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支