全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1277
推到 Plurk!
推到 Facebook!

請教一下指標問題(新手問題)

尚未結案
northwind
一般會員


發表:3
回覆:4
積分:1
註冊:2003-04-09

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-18 18:12:01 IP:61.221.xxx.xxx 未訂閱
請教一下各位先進大大.....我寫了一個dll包一個由c寫的dll...dll的interface如下- unit Iface; interface type PBYTE = ^BYTE; PInteger = ^Integer; PBufferInfo = ^BufferInfo; BufferInfo = {packed }record a1: array[0..12] of Byte; a2: array[0..3] of Byte; a3: array[0..9] of Byte; a4: array[0..127] of Byte; a5: array[0..11] of Byte; end; function FGetSeqNumber(CT1,CT2: PByte;Buffer1,Buffer2,Buffer3: PChar): Integer; stdcall; function CGetSeqNumber(T1,T2: PByte;Buffer: PByte;BufLen: PInteger): Integer; stdcall; function GetInfoBuffer(BufferA: array of Byte): string; implementation uses SysUtils; function CGetSeqNumber; stdcall; external 'cxxx.dll'; function FGetSeqNumber(CT1,CT2: PByte;Buffer1,Buffer2,Buffer3: PChar): Integer; stdcall; Var res: integer; Buffer: BufferInfo; Length: integer; Begin Length := sizeof(Buffer); res:=CGetSeqNumber(CT1,CT2,PByte(@Buffer),@Length); if res=0 then begin StrPCopy(Buffer1,GetInfoBuffer(Buffer.VisitDt) GetInfoBuffer(Buffer.SeqNum) GetInfoBuffer(Buffer.HospNum)); StrPCopy(Buffer2,GetInfoBuffer(Buffer.SAMID)); StrPCopy(Buffer3,GetInfoBuffer(Buffer.SafeSmp)); result:=0; end else result:=res; end; function GetInfoBuffer(BufferA: array of Byte): string; var i: Integer; tmp: string; begin for i := Low(BufferA) to High(BufferA) do begin tmp := tmp chr(BufferA[i]); end; Result := trim(tmp); end; end. 我只有export出來FGetSeqNumber介面讓外部的程式呼叫... 廠商的c的dll的介面為FGetSeqNumber(char* C1,char* C2,char *pBuffer1,int *iBufLen ) 但呼叫時卻沒辦法接回Buffer的資料....老是出現記憶體位址不可為write的錯誤訊息.....是我指標傳錯了嗎......請各位前輩幫幫我吧.....thx
derekcylin
一般會員


發表:0
回覆:7
積分:6
註冊:2003-04-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-04-20 21:42:53 IP:61.230.xxx.xxx 未訂閱
使用不同語言之間的函式呼叫最重要的一件是參數傳遞的問題. 在Delphi中, 它支援了好幾種的參數傳遞, 包括有: Calling conventions Directive Parameter order Clean-up Passes parameters in registers? register Left-to-right Routine Yes pascal Left-to-right Routine No cdecl Right-to-left Caller No stdcall Right-to-left Routine No safecall Right-to-left Routine No 在C中呢, 如果是用VC 6寫的, 則可以在comipler選項中指定calling conversions的方法, 內設為cdecl這字的意思就是"C decleration". 而Windows API是用stdcall...這些差別有兩個, 一個是呼叫前參數存入stack的順序, 另一個就是函式執行完之後, 該由誰來釋放參數. 這在Delphi on-line help都有詳細的解釋喔^.^ 所以你的狀況很可能要把stdcall改成cdecl..試試看吧..
northwind
一般會員


發表:3
回覆:4
積分:1
註冊:2003-04-09

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-04-21 10:41:45 IP:61.221.xxx.xxx 未訂閱
剛試了一下還是不行.....用debug看Buffer有接回來值....但實在不知要如何寫才可將buffer中的值轉成字串傳給外部的程式使用....到底是要怎麼傳外部才接的到..現在外部用其它語言寫call此delphi的dll都是位址錯誤的訊息....請各位前輩教教我吧....謝謝..... 發表人 - northwind 於 2003/04/21 16:21:58
derekcylin
一般會員


發表:0
回覆:7
積分:6
註冊:2003-04-16

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-04-21 17:35:20 IP:211.21.xxx.xxx 未訂閱
PChar要轉成Delphi可以用的字串, 如果是ANSI的字串可以用 function StrPas(Value : PChar) : string; 這個函式 如果是PWHCAR的話可以強制用WideString轉換.
northwind
一般會員


發表:3
回覆:4
積分:1
註冊:2003-04-09

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-04-21 18:51:55 IP:61.221.xxx.xxx 未訂閱
對不起..因為我現在用delphi寫測試程式是ok的但如果外部是別的語言寫的測試程式call此dll卻出現沒辦法回接,記憶體錯誤的情形,那到底buffer要宣告成何種形態外部其它語言寫的測試程式才可回接.....謝謝......
derekcylin
一般會員


發表:0
回覆:7
積分:6
註冊:2003-04-16

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-04-24 14:43:11 IP:211.21.xxx.xxx 未訂閱
因為C的盛行, 字串的傳遞多半是用char *以0為結尾的方式傳的, 這也是Windows API所使用的方式. 而接收端所用的語言則要考慮如何去轉換這個char*的格式, 我想所有WINDOWS平台的程式語言一定都有這個機制的. 在DELPHI中string的規格有許多種, 早期string的格式會在變數所指的位置放上字串長度, 然後程式會依此去它的後面去抓到字串內容, 也因為第一個BYTE是放長度, 所以早期的字串最長只有255. 後來為了擴充, 也為了方便和Windows API做交換, 所以宣告為AnsiString的變數所指的位置變為直接指到字串內容的起始位置, 而長度則記著這個位置之前, 而且在字串最後會補上0, 也因為string type的變數直接強制轉換成PChar()是可行的. 這方便了DELPHI呼叫API不用再多做一些有的沒的. 至於StrPas呢, 其實它只是在函式的STACK上幫程式建立了一個字串, 然後把PCHAR的內容給拷過來而已. 至於其它語言呢, 就要看該語言怎麼去轉這個char*了.
系統時間:2024-04-29 18:33:04
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!