原代码如下:
unit uComm;interfaceuses SPComm;var
  gComm: TComm;
  bufRece, bufSend: array[0..255] of Byte;// 就是想给gComm.OnReceiveData事件赋值的函数定义
procedure DoReceiveData(Sender: TObject; Buffer: Pointer; BufferLength: Word);function ComOpen(AComName: string; ABaudRate: LongInt): LongInt; stdcall;implementation// 就是想给gComm.OnReceiveData事件赋值的函数内容
procedure DoReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);
begin
  Move(Buffer^, bufRece, BufferLength);
end;function ComOpen(AComName: string; ABaudRate: LongInt): LongInt;
begin
  if gComm <> nil then
  begin
    gComm.StopComm;
    gComm.Free;
  end;
  gComm := TComm.Create(nil);
  gComm.CommName := 'COM3';
  gComm.BaudRate := 115200;
  gComm.OnReceiveData := DoReceiveData;
  gComm.StartComm;  Result := 1;
end;在调用“gComm.OnReceiveData := DoReceiveData;”时程序出错了,
我根据以往的记忆,应该是这个DoReceiveData函数定义不对的。请高手告诉问题如何解决?
谢谢!

解决方案 »

  1.   

    procedure DoReceiveData(Sender: TObject; Buffer: Pointer; BufferLength: Word);
    这个要定义在对象里吧,或者这样:
    Type
      TMyRece = procedure DoReceiveData(Sender: TObject; Buffer: Pointer; BufferLength: Word) of Tobject
      

  2.   

    错了,这样
    Type
      TMyRece = procedure(Sender: TObject; Buffer: Pointer; BufferLength: Word) of Object;
      

  3.   

    简单试了下,不知道你要的是不是这样,一种方法是定义在自己的类里,一种是定义在另外的一个类里:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TMyEventClass = class
        class procedure BtnClickEvent(Sender:TObject);
      end;type
      TForm1 = class(TForm)
        btn1: TButton;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        procedure MyBtnClick(Sender:TObject);
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}{ TForm1 }procedure TForm1.MyBtnClick(Sender: TObject);
    begin
      ShowMessage('Hello');
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      btn1.OnClick:=MyBtnClick;
      btn1.OnClick:=TMyEventClass.BtnClickEvent;
    end;{ TMyEventClass }class procedure TMyEventClass.BtnClickEvent(Sender: TObject);
    begin
      ShowMessage('Click the Button!');
    end;end.
      

  4.   

    目前测试的结果是串口接到数据没有触发OnReceiveData所指定的程序。
    继续跟踪,谢谢!
      

  5.   

    上面的代码是在动态库中实现的,虽然编译已经可以通过,但是SPComm的OnReceiveData事件,不管使用jankercsdn介绍的那种方法关联的,都没有触发,感觉很奇怪!检查全部的程序后发现几个疑点,请高手帮忙出出主意:
      1:
    刚开始我使用动态调用动态库的函数,后来查看网络文档介绍说:动态调用DLL例程在用到时才被调入,用完后就被卸载,大大减少了系统资源的占用,我怀疑因为DLL例程在用完后就被卸载,所以没有等到SPComm的还回数据,于是我改为使用静态调用动态库的方式,SPComm的OnReceiveData事件,还是没有触发。
      2:
    上面的过程我都有使用串口的监视程序来查看串口发送和接受的情况,发送的时候数据完全正确,没有接受到数据,还有我发送数据3次后,虽然程序还继续发送数据,但是串口的监视程序也没有查到发送数据了,更不要说收到数据。很是奇怪,在线等候。
      

  6.   

      3:
    上面的程序都是在串口连接设备的情况下测试的,如果我直接使用串口测试工具将正确的数据发送出去,马上能收到设备还回的信息,而且我也直接写了一个SPComm程序(没有使用动态库的)简单测试,结果也完全正确的收到设备还回的数据。补充说明,还是动态库的程序有问题的。
      

  7.   

    是不是用DLL方式,直接用API来控制串口?没用过DLL包装串口组件的,倒是见过在DLL直接用串口API函数,
    另外,换CPORT这个串口控件试试
      

  8.   

    肯定是打开的。通过其他各种努力和尝试,问题基本解决。但是怎么解决的根本原因还不是很清楚,因为时间问题不想在继续讨论了。现在的解决是在Dll中自己封装SPComm:
      TCOM_Base = class(TObject)
      private
        FCOM: string;           //串口名
        FBaudRate: Cardinal;    //波特率
        
        FCOMM:TComm;
        。
      protected
      public
        constructor Create;
        destructor Destroy; override;
        。
        function OpenCOMM:Boolean;    //打开串口
        function CloseCOMM:Boolean;   //关闭串口
        。
      published
        。
        property OnReceiveData:TReceiveData read FReceiveData write FReceiveData;
      end;
    另外,调用Dll时,也碰到一些问题,同样的程序,使用静态调用可以的程序,改用动态调用就不可以了,手头没有这方面的资料,所以也不想再深究了。谢谢大家的参与。