Delphi呼叫DLL無法傳回字串 |
答題得分者是:syntax
|
comewish
一般會員 ![]() ![]() 發表:1 回覆:7 積分:1 註冊:2010-03-31 發送簡訊給我 |
我使用Delphi開發程式,需要呼叫C++寫的DLL
C 的H檔定義節錄如下: [code cpp] //取得資訊 WLDTW_DLL_API int WDLL_iGetInfo(const int iInfoType/*_INFO_TYPE*/, const int iInput, const char* pszInput, int* piOutput, char* pszOutput); [/code] 我的Delphi宣告如下 [code delphi] function WDLL_iGetInfo(const iInfoType:integer {_INFO_TYPE}; const iInput: integer; const Input: PAnsiChar; var piOutput:Integer; var pszOutput: PAnsiChar): integer; cdecl; external 'WLDTW_DLL.dll'; [/code] 此DLL有提供C sample使用以下的方式呼叫上面的Function [code cpp] char* pszGetSymbolByIdx(int iIdx) { //取得商品名 szSymbol[0] = '\0'; WDLL_iGetInfo(IT_SYMBOL_BY_IDX, iIdx, NULL, NULL, szSymbol); return szSymbol; } [/code] 我把上面的sample轉換為Delphi的方式呼叫function但是無法傳回我需要的字串 [code delphi] function GetSymbolByID( ID : integer) : string ; var FSymbolName : PAnsiChar ; iOutput: integer ; begin FSymbolName := chr(0) ; WDLL_iGetInfo(IT_SYMBOL_BY_IDX, ID ,nil,iOutput, FSymbolName); result := String(FSymbolName) ; end ; [/code] C 的Sample Code可以正確的傳回字串資料,但是我用Delphi寫的code卻只能傳回數字資料,無法傳回文字資料,不知道是那裏出了問題,還望這裏的高手能指導一下。 |
boss.tw
高階會員 ![]() ![]() ![]() ![]() 發表:15 回覆:109 積分:194 註冊:2005-05-17 發送簡訊給我 |
|
comewish
一般會員 ![]() ![]() 發表:1 回覆:7 積分:1 註冊:2010-03-31 發送簡訊給我 |
|
comewish
一般會員 ![]() ![]() 發表:1 回覆:7 積分:1 註冊:2010-03-31 發送簡訊給我 |
事實上stdcall的方式我也試過了,不過結果也是相同
[code delphi] //取得資訊 function WDLL_iGetInfo(const iInfoType:integer {_INFO_TYPE}; const iInput: integer; const Input: PChar; var piOutput:Integer; var pszOutput: PChar): integer; stdcall; external 'WLDTW_DLL_stdcall.dll' index 3; [/code] 這個問題已經卡住我的進度一個多月了,一直無法解決 |
comewish
一般會員 ![]() ![]() 發表:1 回覆:7 積分:1 註冊:2010-03-31 發送簡訊給我 |
|
syntax
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
1. DLL 一定使用 stdcall
2. szSymbol[0] = '\0'; 與 FSymbolName := chr(0) ; 意義不同 szSymbol[0] = '\0'; 表示宣告了 szSymbol ,其 Size = ? 你沒說,並將 [0] 第一位設為 '\0' FSymbolName := chr(0) ; 也是將第一位設為 '\0',但是這行這樣寫,FSymbolName 的總長度將會只有 1 先 SetLentch 或 New 吧 先宣告 var str: String pstr: PChar; 然後設定長度 SetLength(str,100); 轉換為 PChar pstr = PChar(str); 傳入呼叫使用 WDLL_iGetInfo(....., pstr ); 然後直接使用 pstr (注意 回傳後 str 與 pstr 不一定會是相同的東西,應僅使用 pstr) ===================引 用 comewish 文 章=================== 這是WLDTW_DLL 有無stdcall的函數導出的差異 不過我看不太懂就是了 |
comewish
一般會員 ![]() ![]() 發表:1 回覆:7 積分:1 註冊:2010-03-31 發送簡訊給我 |
S大你好:
我有試過你的寫法,不過結果依然相同,我把dll的source code放上來,希望能幫我看一下要如何寫才行 WLDTW_DLL_API int WDLL_iGetInfo(const int iInfoType/*_INFO_TYPE*/, const int iInput, const char* pszInput, int* piOutput, char* pszOutput) { int iRetValue = 0; switch(iInfoType) { case IT_CONNECTION: if (iInput >= 0 && iInput < ST_END_OF_ALL && piOutput != NULL) { *piOutput = g_ServerParam[iInput].iConnectingStatus; } break; case IT_SYMBOL_BY_IDX: //取商品名稱 if (pszOutput != NULL) { strcpy(pszOutput, pszGetSymbolStrByIdx(iInput)); } break; case IT_IDX_BY_SYMBOL: //取商品代碼 if (pszInput != NULL && piOutput != NULL) { *piOutput = iGetSymbolIdxByID(pszInput); } break; default: break; } return iRetValue; }
編輯記錄
comewish 重新編輯於 2010-04-23 08:18:29, 註解 無‧
|
comewish
一般會員 ![]() ![]() 發表:1 回覆:7 積分:1 註冊:2010-03-31 發送簡訊給我 |
問題找到了,不是stdcall的問題,原因出在宣告上面,因為pchar是指標,所以dll中pchar的宣告不能加var,這樣會造成傳入的值是pchar本身的address
所以正確的寫法應該是 function WDLL_iGetInfo(const iInfoType:integer {_INFO_TYPE}; const iInput: integer; const Input: PAnsiChar; var piOutput:Integer; pszOutput: PAnsiChar): integer; cdecl; external 'WLDTW_DLL.dll'; 呼叫的部份也要改一下 function GetSymbolByID( ID : integer) : string ; var FSymbolName : PChar ; str : string ; iOutput: integer ; AAA: array[0..100] of Char; begin //SetLength(FSymbolName,100); StrCopy(AAA, ''); WDLL_iGetInfo(IT_SYMBOL_BY_IDX, ID ,nil,iOutput, AAA); result := String(AAA) ; end ; 雖然程式已經可以運作了,只是我不太懂的地方是,為何不能用pchar而要用array of char,還是希望有人能指點一下。 這樣問題就解決了,不過還是謝謝大家的幫忙。
編輯記錄
comewish 重新編輯於 2010-04-23 21:24:21, 註解 無‧
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |