封装 MSComm 串口读取功能到 DLL 中。

要注意的是:

1,据说D2010之后的,出于安全和兼容性的考虑,DLL无法传送string类型,而改用PChar;

2,数据通过参数传回并保存,否则会被释放掉;

3,参数变量定义成record比较好;记得用指针;

DLL代码:

 

1 library dll1;
2  uses
3 SysUtils,
4 Classes,
5 MSCommLib_TLB, //MSComm的控件;
6 Dialogs, //用于DLL里的提示信息,不用可删除;
7 math, //做ceil之类的计算用,可删除;
8 Variants //读取时函数用;
9 ;
10  type
11 PComm = ^TComm; //定义PComm类型,用于传送参数;
12 TComm = record
13 Str:PChar; //字符型 用 pchar
14 Count:Double; //如果需要用real,推荐用double;
15 end;
16  var
17 MSComm1: TMSComm; //定义串口控件变量;
18  {$R *.res}
19 function OPEN_COMMPORT(TC:PComm):Boolean;stdcall; //定义打开串口的函数;
20 var
21 str:AnsiString; //D2010开始,如果使用COMport控件,readstr要用ansistring了,这里不需要,我们没用comport。
22 begin
23 MSComm1:=TMSComm.Create(nil); //创建mscomm
24 MSComm1.InputMode := comInputModeBinary; // 设置接收数据模式为二进制形式
25 MSComm1.InputLen := 0;
26 MSComm1.InBufferCount := 0; // 清空输入缓冲区
27 MSComm1.OutBufferCount := 0; // 清空输出缓冲区
28 MSComm1.SThreshold := 0;
29 MSComm1.Settings := '9600,n,8,1'; //设置波特率;
30 MSComm1.CommPort := 2; //设置串口;
31 if not MSComm1.PortOpen then
32 begin
33 MSComm1.PortOpen := True; //打开;
34 end;
35 result:= MSComm1.PortOpen;
36 end;
37
38 function GET_COMMPORT:PChar;stdcall; //定义接收串口数据的函数;
39 var
40 buffer: array of Byte; //由于Chr的参数需要byte,so ....
41 PStr:string; //取到的字符串累加用;
42 xt, I:Integer;
43 begin
44 try
45 if MSComm1.InBufferCount <> 0 then
46 begin
47 buffer := MSComm1.Input;
48 MSComm1.InBufferCount := 0;
49 MSComm1.OutBufferCount := 0;
50 xt := VarArrayHighBound(buffer, 1);
51 for I := 0 to xt do
52 begin
53 PStr := PStr + Chr(buffer[I]);
54 end;
55 end;
56 except
57 pstr:='串口读取出错。';
58 end;
59 ShowMessage(Pstr); //用dll显示一下读取到的数据;
60 Result:=PWideChar(PStr); //传回主程序;
61 end;
62
63 exports
64 OPEN_COMMPORT, GET_COMMPORT; //声明两个函数;
65 begin
66 end.
67

 

主程序调用:

 

1 unit loaddllUnit1;
2 interface
3 uses
4 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
5 Dialogs, StdCtrls, OleCtrls, MSCommLib_TLB;
6 type
7 PComm = ^TComm; //同样定义一样的参数变量;
8 TComm = record
9 Str:PChar;
10 Count:Double;
11 end;
12 TGetRecieveData=function(TC:PComm):Boolean;stdcall; //定义函数变量;function 后边的参数要与dll里的相同;
13 TGetRD=function:PChar;stdcall;
14
15 TForm1 = class(TForm)
16 Edit1: TEdit;
17 Button1: TButton;
18 Button2: TButton;
19 MSComm1: TMSComm;
20 procedure Button1Click(Sender: TObject);
21 procedure Button2Click(Sender: TObject);
22 procedure FormDestroy(Sender: TObject);
23 private
24 { Private declarations }
25 public
26 { Public declarations }
27 end;
28 var
29 Form1: TForm1;
30 openCommPort: TGetRecieveData; //定义两个函数变量,用于装载 DLL里读取出来的函数功能;
31 getCommData:TGetRD;
32 CommDLL: THandle;
33 tcvar:PComm;
34 implementation
35 {$R *.dfm}
36 procedure TForm1.Button1Click(Sender: TObject);
37 begin
38 CommDLL := LoadLibrary(PChar('DLL\dll1.dll'));
39 try
40 if (CommDLL <> 0) then
41 begin
42 @openCommPort :=GetProcAddress(CommDLL, 'OPEN_COMMPORT'); //装载两个函数;
43 @getCommData :=GetProcAddress(CommDLL, 'GET_COMMPORT'); //装载两个函数;
44 if (@openCommPort<>nil) and (@getCommData<>nil) then
45 begin
46 //下边随便赋值一下,实际上没用到他们。
47 New(tcvar);
48 tcvar.Str:='COM1';
49 tcvar.Count:=100;
50 openCommPort(tcvar); //打开串口;打开串口;打开串口;打开串口;
51 Dispose(tcvar);
52 Application.MessageBox(PChar('DLL加载成功!'), PChar('提示'),
53 MB_ICONWARNING or MB_OK);
54 end
55 else
56 begin
57 Application.MessageBox(PChar('DLL加载失败!'), PChar('提示'),
58 MB_ICONWARNING or MB_OK);
59 end;
60 end
61 else
62 begin
63 Application.MessageBox(PChar('DLL加载出错,DLL可能不存在!'), PChar('错误'),
64 MB_ICONWARNING or MB_OK);
65 end;
66 finally
67 // FreeLibrary(CommDLL); //这里没有释放,等主程序结束再释放;
68 end;
69 end;
70 procedure TForm1.Button2Click(Sender: TObject);
71 var
72 thestr:Pchar;
73 begin
74 thestr:=getCommData; //从DLL读取串口数据;
75 if thestr<>'' then
76 begin
77 edit1.Text:=Edit1.Text+':'+thestr;
78 end
79 else
80 begin
81 edit1.Text:=Edit1.Text+'BBBB';
82 end;
83 end;
84 procedure TForm1.FormDestroy(Sender: TObject);
85 begin
86 FreeLibrary(CommDLL); //记得释放掉。
87 end;
88 end.
89

 

posted on 2010-11-30 14:03  Delphi2010_老赵  阅读(3378)  评论(0编辑  收藏  举报

导航