C#调用C++DLL的小总结8---C++Dll中函数返回字符串指针
C#調(diào)用C++DLL的小總結(jié)8---C++Dll中函數(shù)返回字符串指針
在這個(gè)系列的“C#調(diào)用C++DLL的小總結(jié)6---C++Dll中指針的釋放問(wèn)題 ”中曾經(jīng)詳細(xì)說(shuō)過(guò)類(lèi)似的問(wèn)題,但今天換了個(gè)馬甲,就又耗費(fèi)了半天的時(shí)間才解決掉,記下來(lái)以為咨詢。
情況如下:
在一個(gè)C++DLL中寫(xiě)了一個(gè)函數(shù)用來(lái)返回?cái)?shù)據(jù)庫(kù)的連接字符串,返回值是一個(gè)char*的指針:
Char p[100] = {0};
Char * Getxxxx_con(xxx,xxx){return p;}
在C#中為了偷懶,直接封裝成了如下:
String Getxxxx_con(xxx,xxx){//此處調(diào)用封裝的導(dǎo)出函數(shù),直接返回即可}
這個(gè)在調(diào)試環(huán)境下沒(méi)有問(wèn)題,直接就可以用。因?yàn)楣こ掏旯ず笠矝](méi)有立即使用,所以測(cè)試也沒(méi)有多么重視。
直到昨天要去現(xiàn)場(chǎng)安裝,才發(fā)現(xiàn)無(wú)法使用,一到調(diào)用這個(gè)函數(shù),不是說(shuō)無(wú)法加載DLL,就是程序就直接崩潰或者掛掉。
考慮有如下幾種情況:
1、中英文環(huán)境的RUNTIME庫(kù)不同引起不同的結(jié)果。以前發(fā)現(xiàn)過(guò)類(lèi)似的問(wèn)題。
2、缺少相應(yīng)的DLL
第一種情況與第二種情況其實(shí)差不多。用一些看DLL的引用軟件(如DEPENDS等),確實(shí)少幾個(gè)庫(kù),增加后,還是崩潰。
而自己的電腦才裝了WIN8_X64,編譯出來(lái)的程序又無(wú)法在別的X32上的平臺(tái)上使用,真是沒(méi)辦法了,只好在服務(wù)器上一點(diǎn)點(diǎn)的弄。
使用中文環(huán)境,安裝中文庫(kù),都不能解決問(wèn)題。晚上回家的路上同上文講得一樣,開(kāi)始考慮這個(gè)DLL調(diào)用的問(wèn)題,因?yàn)樽钚碌膸?kù)都是直接調(diào)用沒(méi)有問(wèn)題,所以仍然可能是這個(gè)DLL寫(xiě)得有問(wèn)題.
早晨來(lái)了后把庫(kù)的函數(shù)增加了一個(gè),只返回INT型,測(cè)試成功,那么懷疑是全局的字符串指針失效。(也就是說(shuō)DLL在加載后RETURN后被釋放掉全局空間指針指向的內(nèi)存無(wú)效,實(shí)際情況并不是如此)直接寫(xiě)了一個(gè)固定的字符串返回,報(bào)無(wú)法操作受保護(hù)的內(nèi)存指針,這里才懷疑到了C#的封裝層面上:
AttendServer.getDbConnectString(addr,port,name,pw);
注意:這個(gè)函數(shù)返回的是string
然后直接NEW了一個(gè)指針回傳,也是報(bào)內(nèi)存問(wèn)題。
這時(shí)候兒才想起了在系列6中的現(xiàn)象:
Marshal.PtrToStringAnsi( AttendServer.getDbConnectString(addr,port,name,pw));
注意下面的函數(shù)返回值IntPtr
public static extern IntPtr getDbConnectString(string addr, int port, string name, string pw);
程序就OK了,本來(lái)想偷懶,結(jié)果反而更費(fèi)時(shí)間。
欲速則不達(dá)啊。只是任誰(shuí)都沒(méi)想到,在調(diào)試時(shí)是可以的,到安裝就不可以了,所以說(shuō)還是對(duì)C#和C++DLL的內(nèi)存空間的操作不熟悉,沒(méi)有深入到其內(nèi)部。二者之間通過(guò)COM來(lái)操作字符串,所以其中很多的東西都需要認(rèn)真的想一下,不能想當(dāng)然的想如何,便如何。
非以小事而勿以為重,以之為鑒。
總結(jié)
以上是生活随笔為你收集整理的C#调用C++DLL的小总结8---C++Dll中函数返回字符串指针的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 编程要养成的好习惯
- 下一篇: C# 通过socket实现UDP 通信