DLL函数返回PCHAR值问题 |
答題得分者是:wyndog
|
cxg
中階會員 ![]() ![]() ![]() 發表:116 回覆:192 積分:76 註冊:2004-02-12 發送簡訊給我 |
我在DLL中定义了一个串口通讯的函数,然后在调用时返回值老是不正确,不知道为什么,但我改成STRING,然后用SHAREMEM就没有问题,但是这样用非DELPHI好像不能调用吧,所以我想改成PCHAR。下面是我的DLL的代码,麻烦各位大虾帮我检查一下。 library DRYPRT5; { Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
SysUtils,
Classes,
PRTTING in 'PRTTING.pas';
{$R *.RES}
EXPORTS
OPEN_PORT, CLOSE_PORT, SEND_COMMAND;
begin
end. //============================================
unit PRTTING; interface USES
Windows, Forms, ExtCtrls, SysUtils, SPComm; TYPE
TMYOBJ = CLASS
PROCEDURE MYComReceiveData(Sender: TObject; Buffer: Pointer; BufferLength: Word);
END; VAR
WAIT_TIMES, N_NUMBER : INTEGER;
START_TIMES : REAL;
READ_BUSY, OPEN_BUSY, PORT_ACTIVE, RECEIVE_FINISH : BOOLEAN;
S_DATA : STRING; MYCOM : TCOMM;
MYOBJ : TMYOBJ; FUNCTION OPEN_PORT( PORT : SHORTSTRING; BTL : INTEGER) : INTEGER;STDCALL;
FUNCTION CLOSE_PORT : INTEGER;STDCALL;
FUNCTION SEND_COMMAND( SD : STRING; VAR RD : PChar) : INTEGER;STDCALL; implementation PROCEDURE INI_OBJ;
begin
MYOBJ := TMYOBJ.Create;
MYCOM := TComm.Create( NIL);
MYCOM.OnReceiveData := MYOBJ.MYComReceiveData;
end; PROCEDURE FREE_OBJ;
BEGIN
TRY
IF MYOBJ<>NIL THEN
BEGIN
MYOBJ.FREE;
MYOBJ := NIL;
END;
IF MYCOM<>NIL THEN
BEGIN
MYCOM.FREE;
MYCOM := NIL;
END;
EXCEPT
END;
END; PROCEDURE TMYOBJ.MYComReceiveData(Sender: TObject; Buffer: Pointer; BufferLength: Word);
VAR
S1 : STRING;
BEGIN
START_TIMES := NOW;
SetLength( S1, BufferLength);
MOVE( Buffer^, PCHAR(S1)^, BufferLength);
S_DATA := S_DATA S1; IF POS( #13, S_DATA)>0 THEN RECEIVE_FINISH := TRUE;
END; FUNCTION SEND_COMMAND( SD : STRING; VAR RD : PChar) : INTEGER;STDCALL;
VAR
N2 : REAL;
B : BOOLEAN;
BEGIN
IF READ_BUSY THEN
BEGIN
RESULT := 0;
EXIT;
END;
IF NOT PORT_ACTIVE THEN
BEGIN
RESULT := -1;
EXIT;
END;
READ_BUSY := TRUE;
RECEIVE_FINISH := FALSE;
START_TIMES := NOW;
S_DATA := '';
MYCOM.WriteCommData( SD); B := FALSE;
WHILE NOT RECEIVE_FINISH DO
BEGIN
APPLICATION.ProcessMessages;
N2 := NOW - START_TIMES;
N2 := N2 * 100000000;
B := N2 > 2000;
IF B THEN BREAK;
END;
IF B THEN RESULT := -2 // 超时没有返回值
ELSE RESULT := 1;
RD := PCHAR( S_DATA);
S_DATA := '';
READ_BUSY := FALSE;
END; FUNCTION OPEN_PORT( PORT : SHORTSTRING; BTL : INTEGER) : INTEGER;STDCALL;
BEGIN
IF OPEN_BUSY OR READ_BUSY THEN
BEGIN
RESULT := 0;
EXIT;
END;
IF PORT_ACTIVE THEN
BEGIN
RESULT := -1;
EXIT;
END;
OPEN_BUSY := TRUE;
INI_OBJ; MYCOM.BaudRate := BTL;
MYCOM.CommName := PORT;
TRY
MYCOM.StartComm;
PORT_ACTIVE := TRUE;
RESULT := 1;
EXCEPT
PORT_ACTIVE := FALSE;
RESULT := -2;
END;
OPEN_BUSY := FALSE;
END; FUNCTION CLOSE_PORT : INTEGER;STDCALL;
BEGIN
TRY
IF MYCOM<>NIL THEN MYCOM.StopComm;
PORT_ACTIVE := FALSE;
RESULT := 1;
EXCEPT
RESULT := -1;
END; FREE_OBJ;
END; end.
|
wyndog
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:7 回覆:362 積分:348 註冊:2004-10-12 發送簡訊給我 |
|
cxg
中階會員 ![]() ![]() ![]() 發表:116 回覆:192 積分:76 註冊:2004-02-12 發送簡訊給我 |
|
wyndog
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:7 回覆:362 積分:348 註冊:2004-10-12 發送簡訊給我 |
你的 RD 是需要傳回來的
所以,如果考慮到記憶體分配的問題
最好是在呼叫端配置比較好
也就是說,在呼叫 SEND_COMMAND 前先配好記憶體
所以在 Delphi 裡,要變這樣 SetLength(RD, 256); // 分配好適度的空間
SEND_COMMAND(PChar(SD), PChar(RD)); 再來就是,SEND_COMMAND 裡,要把 RD := PChar(S_DATA); 這段改掉
改成 Move(S_DATA[1], RD^, length(S_DATA));
把 S_DATA 複製到 RD 去,而不要讓 RD 直接傳回 Pointer
|
cxg
中階會員 ![]() ![]() ![]() 發表:116 回覆:192 積分:76 註冊:2004-02-12 發送簡訊給我 |
|
wyndog
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:7 回覆:362 積分:348 註冊:2004-10-12 發送簡訊給我 |
|
cxg
中階會員 ![]() ![]() ![]() 發表:116 回覆:192 積分:76 註冊:2004-02-12 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |