C#調(diào)用C++ DLL bool返回值始終為true的問題
C#調(diào)用C++ DLL bool返回值始終為true
問題描述
在C#項(xiàng)目中,調(diào)用C++ DLL中方法時(shí),bool 返回值始終返回true。
問題原因
C將布爾定義為4字節(jié)int,C++將其定義為1字節(jié)。C#團(tuán)隊(duì)決定在PInvoke期間使用4字節(jié)bool作為默認(rèn)值,因?yàn)榇蠖鄶?shù)系統(tǒng)API函數(shù)使用4字節(jié)值作為bool。如果要更改此行為,必須通過封送處理來完成,并指定要使用1字節(jié)值。
解決方案
方案一
采用int 返回值替代bool返回值,如返回1代表true,返回0代表false。
方案二
通過[return:MarshalAs(UnmanagedType.I1)] 指定返回值為1字節(jié)值。
[DllImport("Whisper.dll", EntryPoint="Exist", CallingConvention=CallingConvention.Cdecl)]
[return:MarshalAs(UnmanagedType.I1)]
public static extern bool Exist([MarshalAs(UnmanagedType.LPStr)] string name);C#調(diào)用C++的DLL返回值為bool時(shí),值混亂
現(xiàn)象:C++ 導(dǎo)出函數(shù)的返回值為 false,C# 調(diào)用該函數(shù)獲取的返回值卻為 true 。
原因:C++ 導(dǎo)出函數(shù)返回 false 時(shí),采取的方式是:
將 C# 定義的用來接收返回值的 bool 所指的地址開始 4 個(gè)字節(jié)設(shè)為 0x01000000(見圖1)。
注:用 C++ 代碼調(diào)用該導(dǎo)出函數(shù)時(shí),采取的方式是:將 C++ 定義的用來接收返回值的 bool 所指的地址開始 1 個(gè) 字節(jié)設(shè)為 0x00;
為什么用 C# 代碼調(diào)用該導(dǎo)出函數(shù)時(shí),采取的方式不是:將 C# 定義的用來接收返回值的 bool 所指的地址開始 1個(gè) 字節(jié) 設(shè)為 0x00 ? —— 編譯器問題(BUG?)。
圖 1

解決方案
在 C++ 導(dǎo)出函數(shù)中使用 BOOL 代替 bool 。
注:由于C++ 中的 BOOL 占4個(gè)字節(jié),
C++ 導(dǎo)出函數(shù)返回 false 時(shí),采取的方式是:
將 C# 定義的用來接收返回值的 bool 所指的地址開始 4 個(gè)字節(jié)設(shè)為0x00000000(見圖2),因此不存在上述問題。
圖 2

圖3

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C#多線程開發(fā)實(shí)戰(zhàn)記錄之線程基礎(chǔ)
線程是一個(gè)獨(dú)立的運(yùn)行單元,每個(gè)進(jìn)程內(nèi)部有多個(gè)線程,每個(gè)線程可以各自同時(shí)執(zhí)行指令,每個(gè)線程有自己獨(dú)立的棧,但是與進(jìn)程內(nèi)的其他線程共享內(nèi)存,這篇文章主要給大家介紹了關(guān)于C#多線程開發(fā)實(shí)戰(zhàn)記錄之線程基礎(chǔ)的相關(guān)資料,需要的朋友可以參考下2021-09-09
C#提取網(wǎng)頁中超鏈接link和text部分的方法
這篇文章主要介紹了C#提取網(wǎng)頁中超鏈接link和text部分的方法,涉及C#正則表達(dá)式及字符串操作相關(guān)技巧,需要的朋友可以參考下2016-02-02
Unity Shader實(shí)現(xiàn)玻璃材質(zhì)效果
這篇文章主要為大家詳細(xì)介紹了Unity Shader實(shí)現(xiàn)玻璃材質(zhì)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04

