⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extdllp.dpr

📁 VSPM 虚拟串口软件可以将TCP/IP、UDP广播映射成本机的虚拟COM 口
💻 DPR
字号:
library extdll;


uses
  SysUtils,
  SyncObjs,
  Dialogs,
  Classes,
  VComRes in 'VComRes.pas';                  

{
此DLL演示如何让VSPM具备自动轮询功能,并将轮询到的数据处理后,发给虚拟串口。
}

type
   PDllData=^TDllData;
   TDllData = array of Byte;
   
var
  //COM口对应的资源
  ComRes:TStringlist;
  

{$R *.res}

function GetComResByName(const VComName:string;var odata:TVComResClass):boolean;
var
  AVComResClass:TVComResClass;
  i1:Integer;
begin
  //用串口名,获得对应的串口资源
Result:=false;
  i1:=ComRes.IndexOf(VComName);
  if i1<0 then exit;
  AVComResClass:=TVComResClass(ComRes.Objects[i1]);
  odata:=AVComResClass;
   //释放资源
  Result:=Assigned(AVComResClass);
end;

procedure InitExtDll(var act:integer);stdcall;
begin
  //初始化扩展DLL资源
  //VSPM在加载成功后调用此函数
  ComRes:=TStringlist.Create;
  act:=0;

end;

procedure FreeExtDll(var act:integer);stdcall;
begin
  //释放扩展资源
  //在DLL释放前,VSPM调用此函数
    FreeAndNil(ComRes);
  act:=0;
end;

procedure VComEvent(idata:Pointer;var act:integer);stdcall;
var
AVComResClass:TVComResClass;
SerialName:string;
i1:integer;
begin
  //虚拟串口消息
  
  //idata,虚拟串口号。
  //act=0,虚拟串口打开消息
  //act=1,虚拟串口关闭消息
  //act=10,虚拟串口建立消息
  //act=11,虚拟串口删除消息

  SerialName:=PChar(idata);
  case act of
    0:begin
      end;
    1:begin
      end;
   10:begin
      //建立虚拟串口,时初始化资源
      //如果对应的串口资源已经建立,退出
      if ComRes.IndexOf(SerialName)>=0 then exit;
      //建立此串口资源
      AVComResClass:=TVComResClass.Create(SerialName);
      //添加资源到列表
      ComRes.AddObject(SerialName,AVComResClass);
      end;
   11:begin
       //删除虚拟串口
      //如果没有对应的串口资源,退出
      i1:=ComRes.IndexOf(SerialName);
      if i1<0 then exit;
       AVComResClass:=TVComResClass(ComRes.Objects[i1]);
       //释放资源
       if Assigned(AVComResClass) then FreeAndNil(AVComResClass);
      end;
   end;
  act:=0;
  //串口消息

end;

procedure VComQueryEvent(VComName:Pchar;
                             const odata:Pointer;var odatasize:Integer;
                             var act:integer);stdcall;export;
begin
   //VComQueryEvent->虚拟串口,在串口对应的TCP/IP连接失效时,VSPM调用此函数
   //此函数用于向应用程序发出串口数据报文。
   //相当于应用程序从虚拟串口收到由TVComQueryEvetn产生的数据。
   //参数:虚拟串口名称,输出数据,输出数据尺寸,
   //act操作//(dll返回:act=0-发送数据)
            //(dll返回:act=1-不发送数据,忽略此函数功能)
   //!!VSPM Server模式下不调用此函数!!
   
  //不需要此函数
  act:=1;
end;


//NetworkQuery
procedure NetQueryEvent(VComName:Pchar;
                            const odata:Pointer;var odatasize:Integer;
                            var act:integer);stdcall;export;
begin
  //不需要此函数
  //NetQueryEvent->TCP/IP网络模拟发送函数,只有当网络连接正常时,
  //并且虚拟串口关闭时才会调用此函数
  //参数:虚拟串口名称,输出数据,输出数据尺寸,
  //act操作 //(dll返回:act=0-发送数据)
             //(dll返回:act=1-不发送数据,忽略此函数功能)
  act:=1;
end;


//虚拟串口接收
procedure VComRecEvent(VComName:Pchar;idata:Pointer;idatasize:Integer;
                             const odata:Pointer;var odatasize:Integer;
                             var act:integer); stdcall;export;
var
  s1:string;
  lodata:PDllData;
begin
  //对应的虚拟串口打开后,由VSPM线程一直调用此函数。
  //因为由此DLL进行轮询,所以此函数忽略idata,
  //模拟召唤报文
  s1:='Polling:Need data';
  lodata:=PDllData(odata);
  //输出数据长度
  odatasize:=Length(s1);
  //复制数据到输出缓冲
  Move(s1[1],lodata^,odatasize);
  //发送到网络,
  act:=0;

  //500毫秒轮询一次
  Sleep(500);          
end;

procedure AfterVComRecEvent(VComName:Pchar;idata:Pointer;idatasize:Integer;
                              const odata:Pointer;var odatasize:Integer;
                             var act:integer); stdcall;export;
var
      AWaitresult:TWaitResult;
      AComResClass:TVComResClass;                
begin
//发送数据到TCP/IP后执行此函数
act:=0;
odatasize:=idatasize;
  //取得此串口对应的资源
  if not GetComResByName(VComName,AComResClass) then exit;
  //等待网络数据返回,如果1秒钟内远程没有返回数据,判定为轮询未响应。
  AWaitresult:=AComResClass.GResponEvent.WaitFor(1000);
  if  (AWaitresult=wrSignaled) then
      begin
        //响应轮询
      end else
      begin
         //在此处处理轮询未响应错误。
         Beep;
         exit;
      end;

end;





procedure NetRecEvent(VComName:Pchar;idata:Pointer;idatasize:Integer;
                             const odata:Pointer;var odatasize:Integer;
                             var act:integer); stdcall;export;
var
  s1:string;
  lidata,lodata:PDllData;
  AComResClass:TVComResClass;
  
begin
  //当从网络接收到数据时,调用此函数
  act:=1;
  if (idatasize<=0) then exit;
  lidata:=PDllData(idata);
  lodata:=PDllData(odata);
  
  SetLength(s1,idatasize);
  //复制输入数据到本地缓冲                
  Move(lidata^,s1[1],idatasize);
                        
  if (s1='Polling:Data') then
     begin
        //取得此串口对应的资源
        if not GetComResByName(VComName,AComResClass) then exit;
       //如果收到的是数据报文,转换为显示报文
        s1:=Format(#10#13'收到回应报文(%d):<%s>'#10#13,[AComResClass.FrameCount,s1]);
        //输出数据长度
        odatasize:=Length(s1);
        //复制数据到输出缓冲
        Move(s1[1],lodata^,odatasize);
        //通知AfterVComRecEvent已经收到由设备返回来的数据
         AComResClass.GResponEvent.SetEvent;
         Inc(AComResClass.FrameCount);
     end else
     begin
       //其他报文不处理
       odatasize:=0;
       act:=1;
     end;

  act:=0;
end;
 
procedure AfterNetRecEvent(VComName:Pchar;idata:Pointer;idatasize:Integer;
                             const odata:Pointer;var odatasize:Integer;
                             var act:integer); stdcall;export;
begin
//不处理此函数
odatasize:=idatasize;
act:=0;
end;

exports
InitExtDll,
FreeExtDll,

VComRecEvent,
AfterVComRecEvent,

VComQueryEvent,
NetRecEvent,
AfterNetRecEvent,
NetQueryEvent,
VComEvent;
begin


end.


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -