红色部分改动后,原来的E2009 Incompatible types : 'method pointer and regular procedure' 错误提示没了,可串口接收事件根本不激活。即使定时查询串口也读不到任何数据。部分主要代码,贴出如下:
为什么?请各位高手帮帮忙。谢谢。分数有限,只能将所有分都拿出来了,别嫌少。library ComPortDLL;uses
ShareMem, SysUtils, CPort, Windows, Classes;type
TABC=class(TComponent)
procedure CommPortRxChar(Sender:TObject; Count: Integer);
end;{$R *.res}
var
ABC : TABC;
CommPort : TComPort;
DataReadFromCommPort : string;
procedure TABC.CommPortRxChar(Sender: TObject; Count: Integer);
var ByteReaded,temp : integer;
strReaded : String;
begin
ByteReaded := CommPort.ReadStr(strReaded,count);
DataReadFromCommPort := DataReadFromCommPort+strReaded;
while ByteReaded<Count do begin
temp := CommPort.ReadStr(strReaded,Count-ByteReaded);
if temp>0 then begin
ByteReaded := ByteReaded + temp;
DataReadFromCommPort := DataReadFromCommPort+strReaded;
end;
end;
end;procedure InitStatus();
begin
DataReadFromCommPort := '';
end;//打开串口
function OpenSerialPort(uPort, tBaudRate : integer) : boolean; stdcall;
begin
if (CommPort<>nil) then begin
CommPort.Close;
CommPort.Destroy;
end; CommPort := TComPort.Create(nil);
CommPort.Port := 'COM'+IntToStr(uPort);
case tBaudRate of
0: CommPort.BaudRate := br300;
1: CommPort.BaudRate := br600;
2: CommPort.BaudRate := br1200;
3: CommPort.BaudRate := br2400;
4: CommPort.BaudRate := br4800;
5: CommPort.BaudRate := br9600;
6: CommPort.BaudRate := br14400;
7: CommPort.BaudRate := br19200;
8: CommPort.BaudRate := br38400;
9: CommPort.BaudRate := br56000;
10: CommPort.BaudRate := br57600;
11: CommPort.BaudRate := br115200;
end;
CommPort.DataBits := dbEight;
CommPort.StopBits := sbOneStopBit;
CommPort.SyncMethod := smWindowSync;
CommPort.OnRxChar := ABC.CommPortRxChar;
CommPort.Open;
Result := CommPort.Connected;
end;//关闭串口
procedure StopCom(); stdcall;
begin
if (CommPort<>nil) then begin
CommPort.Close;
CommPort.Destroy;
end;
CommPort := nil;
end;//发送 AT 指令
function SendComCommand(sendStr : String) : integer; stdcall;
begin
Result := 0;
if ((CommPort.Connected) and (sendStr<>'')) then begin
Result := CommPort.WriteStr(sendStr+#$D);
end;
end;Exports
OpenSerialPort, StopCom, SendComCommand;begin
InitStatus;
ABC := TABC.Create(nil);
end.
为什么?请各位高手帮帮忙。谢谢。分数有限,只能将所有分都拿出来了,别嫌少。library ComPortDLL;uses
ShareMem, SysUtils, CPort, Windows, Classes;type
TABC=class(TComponent)
procedure CommPortRxChar(Sender:TObject; Count: Integer);
end;{$R *.res}
var
ABC : TABC;
CommPort : TComPort;
DataReadFromCommPort : string;
procedure TABC.CommPortRxChar(Sender: TObject; Count: Integer);
var ByteReaded,temp : integer;
strReaded : String;
begin
ByteReaded := CommPort.ReadStr(strReaded,count);
DataReadFromCommPort := DataReadFromCommPort+strReaded;
while ByteReaded<Count do begin
temp := CommPort.ReadStr(strReaded,Count-ByteReaded);
if temp>0 then begin
ByteReaded := ByteReaded + temp;
DataReadFromCommPort := DataReadFromCommPort+strReaded;
end;
end;
end;procedure InitStatus();
begin
DataReadFromCommPort := '';
end;//打开串口
function OpenSerialPort(uPort, tBaudRate : integer) : boolean; stdcall;
begin
if (CommPort<>nil) then begin
CommPort.Close;
CommPort.Destroy;
end; CommPort := TComPort.Create(nil);
CommPort.Port := 'COM'+IntToStr(uPort);
case tBaudRate of
0: CommPort.BaudRate := br300;
1: CommPort.BaudRate := br600;
2: CommPort.BaudRate := br1200;
3: CommPort.BaudRate := br2400;
4: CommPort.BaudRate := br4800;
5: CommPort.BaudRate := br9600;
6: CommPort.BaudRate := br14400;
7: CommPort.BaudRate := br19200;
8: CommPort.BaudRate := br38400;
9: CommPort.BaudRate := br56000;
10: CommPort.BaudRate := br57600;
11: CommPort.BaudRate := br115200;
end;
CommPort.DataBits := dbEight;
CommPort.StopBits := sbOneStopBit;
CommPort.SyncMethod := smWindowSync;
CommPort.OnRxChar := ABC.CommPortRxChar;
CommPort.Open;
Result := CommPort.Connected;
end;//关闭串口
procedure StopCom(); stdcall;
begin
if (CommPort<>nil) then begin
CommPort.Close;
CommPort.Destroy;
end;
CommPort := nil;
end;//发送 AT 指令
function SendComCommand(sendStr : String) : integer; stdcall;
begin
Result := 0;
if ((CommPort.Connected) and (sendStr<>'')) then begin
Result := CommPort.WriteStr(sendStr+#$D);
end;
end;Exports
OpenSerialPort, StopCom, SendComCommand;begin
InitStatus;
ABC := TABC.Create(nil);
end.
SysUtils,
Classes,
Frm_cPort in 'Frm_cPort.pas';{$R *.res}exports SetCallback,
OpenPort,
ClosePort,
WriteStr;begin
end.//////////////////////////////////////////////////////////////////////////////////////////////////unit Frm_cPort;interfaceuses
Windows, SysUtils, CPort, CPortCtl;type
TCallback = procedure(s: pchar); stdcall; //回调 TMy_cPort_OBJ= class
procedure My_cPortRxChar(Sender: TObject; Count: Integer);
end; var
My_cPort: TComPort;
My_cPort_OBJ: TMy_cPort_OBJ;
FCallback: TCallback; //回调 function WriteStr(SD: string): integer; stdcall;
procedure SetCallback(ACallback: TCallback); stdcall; //回调
function OpenPort(Port: shortstring; BTL: integer): integer; stdcall;
function ClosePort: integer; stdcall;
implementation
procedure INI_cPort;
begin
My_cPort := TComPort.Create(nil);
My_cPort.OnRxChar := My_cPort_OBJ.My_cPortRxChar;
end;procedure FREE_cPort;
begin
try
if My_cPort_OBJ <> nil then
begin
My_cPort_OBJ.FREE;
My_cPort_OBJ := nil;
end; if My_cPort <> nil then
begin
My_cPort.FREE;
My_cPort := nil;
end;
except
end;
end;procedure SetCallback(ACallback: TCallback); stdcall;
begin
FCallback := ACallback;
end;
procedure TMy_cPort_OBJ.My_cPortRxChar(Sender: TObject; Count: Integer); //接收
var
Str: string;
begin
My_cPort.ReadStr(Str, Count);
if Assigned(FCallback) then
FCallback(pchar(Str));
end;
function WriteStr(SD: string): INTEGER; stdcall; //发送
begin
My_cPort.WriteStr(SD);
end;
function OpenPort(Port: shortstring; BTL: INTEGER): INTEGER; stdcall;
begin
INI_cPort; My_cPort.Port := 'com' + Port;
My_cPort.BaudRate := br9600; //BTL自行修改 //TBaudRate = (brCustom, br110, br300, br600, br1200, br2400, br4800, br9600, br14400,
//br19200, br38400, br56000, br57600, br115200, br128000, br256000);
//My_cPort.StopBits :=
//My_cPort.DataBits :=
//My_cPort.Buffer :=
try
My_cPort.Connected := true;
RESULT := 1;
except
RESULT := -1;
end;end;function ClosePort: INTEGER; stdcall;
begin
try
if My_cPort <> nil then
My_cPort.Connected := false;
RESULT := 2;
except
RESULT := -2;
end;
FREE_cPort;
end;
initialization
//CoInitialize(nil);
finalization
//CoUninitialize;end.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
DEMO程序
unit FrmMain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;type
TCallback = procedure(s: pchar); stdcall;var
Form1: TForm1;function OpenPort(PORT: shortstring; BTL: integer): integer; stdcall External 'cPort_DLL.dll';
function ClosePort: integer; stdcall External 'cPort_DLL.dll';
function WriteStr(SD: string): integer; stdcall External 'cPort_DLL.dll';
procedure SetCallback(ACallback: TCallback); stdcall External 'cPort_DLL.dll';
procedure CallbackExample(s: pchar); stdcall;implementation{$R *.dfm}procedure CallbackExample(s: pchar); stdcall;
begin
Form1.Memo1.Text := Form1.Memo1.Text + ' ' + (s);
end;procedure TForm1.Button1Click(Sender: TObject);
begin
OpenPort('1',9600);
SetCallback(@CallbackExample); //设置回调
end;procedure TForm1.Button2Click(Sender: TObject);
begin
ClosePort;
end;procedure TForm1.Button3Click(Sender: TObject);
begin
WriteStr('hello');
end;end.
主函数不能直接CommPort := TComPort.Create(nil);
spcomm这样没有问题的
//CPort.SyncMethod := smNone; call events inside monitoring thread;可行//;
//CPort.SyncMethod := smThreadSync; call events in main thread 不可行 DoEvents执行不了,应该是主程序调用DLL,DLL里面再操作TComThread出的问题。
function OpenPort(Port: shortstring; BTL: Integer): Integer; stdcall;
begin
INI_cPort; CPort.BeginUpdate;
CPort.Port := 'com3';
CPort.BaudRate := br115200; //BTL自行修改 CPort.DataBits := dbEight;
CPort.StopBits := sbOneStopBit;
CPort.Parity.Bits := prNone;
CPort.FlowControl.FlowControl := fcNone;
CPort.SyncMethod := smNone;//smThreadSync; //此处注意
CPort.EndUpdate; try
CPort.Open;
RESULT := 1;
except
RESULT := -1;
end;end;
不过可以手动添加,可以看看Delphi中DLL的消息处理和DLL 线程同步问题方面的东西。
给你一个链接 http://explorer.javaeye.com/blog/106033
http://explorer.javaeye.com/blog/106033我仔细学习一下。
感谢,试过之后再请教。
道理是明白了,但具体操作不懂。
CommPort.SyncMethod := smWindowSync; 应该是解决这个问题的办法,我从dinglinger的帖子中学到的,为什么到我这里不行,还请再详细指点一下。
谢谢。
现在遇到的问题是CPort的发送数据没问题,但OnRXChar事件不能激活,就是这部分。
procedure TMy_cPort_OBJ.My_cPortRxChar(Sender: TObject; Count: Integer); //接收
var
Str: string;
begin
My_cPort.ReadStr(Str, Count);
if Assigned(FCallback) then
FCallback(pchar(Str));
end;
为什么CPort不行,而同样是动态生成的Timer的OnTimer事件却可以?但在OnTimer事件中手动也收不到任何接收数据?是不是在DLL中CPort就收不到数据。
不使用Synchronize就可以了
测试环境是 Delphi 2006吗?
谢了
能给个小例子吗。?
最好有注释
mail:[email protected]
折腾这么久,大家的测试都没问题,问题肯定出在自己这边,以前一直是将串口连接在设备上的,重新做了一根串口自环线,一看果然能正常工作,仔细对照了一下设备手册,结果发现自己犯了一个低级错误。
CPort.FlowControl.FlowControl := fcHardware; 应该是硬件流控。
非常感谢 oosmile.
惭愧~~~我也碰到一样的问题,自己找到了应该是修改SyncMethod属性为smWindowSync,但是修改后无效~~~再三仔细一看。同时支持CPort和SPComm,把代码写到了下面~~~~~晕啊,把代码贴出来,后人有个借鉴。
procedure CreateComm;
begin
{$IFDEF CPORT3}
if CommPort = nil then
begin
CommPort := TComPort.Create(nil);
end; CommPort.OnRxBuf := TDummy.OnComPortRxBuf;
CommPort.TriggersOnRxChar := False;
{$ELSE}
if CommPort = nil then
CommPort := TComm.Create(nil); CommPort.SyncMethod := smWindowSync;
CommPort.OnReceiveData := TDummy.OnReceiveData;
{$ENDIF}
end;