Crear un puerto serie virtual

Un puerto virtual es un dispositivo muy útil a la hora de trabajar con aplicaciones pensadas para trasmitir y recibir datos a través del puerto serie. Puede servir, por ejemplo, para leer los datos que un programa envía a una impresora o a un visor a través de un puerto serie, y luego utilizarlos en otra aplicación. En mi caso yo lo utilizo para para leer los datos que un programa manda a un supuesto visor, modificar esos datos, y luego mandar los nuevos datos al puerto serie real donde esta conectado el visor.

Se pueden descargar de Internet diferentes programas para simular un puerto serie, pero yo me he decidido a usar el de ETERLOGIC.COM©, que es gratuito en su versión de 32 bits. Una vez instalado, podemos crear diferentes tipos de puertos, uno de ellos es el tipo "Conector" que no es mas que un puerto serie que puede ser utilizado por dos aplicaciones a la vez, de forma que lo que una escribe en el puerto lo lee la otra y viceversa. Así una vez creado solo tenemos que usar las funciones habituales para manejar un puerto serie, despreocupandonos del hecho de que se trata de un puerto virtual.

El único problema entonces es crear el puerto virtual. Con la instalación del VSPE de ETERLOGIC.COM© se instala también un programa que nos permite gestionar los puertos virtuales (crearlos, borrarlos, etc ...) el problema es que los puertos que se crean desde este programa no se mantienen una vez que se reinicia el ordenador. Así que, si queremos usar un puerto virtual en una de nuestras aplicaciones tenemos dos alternativas, crear el puerto manualmente cada vez que lo necesitemos, o crearlo desde nuestra aplicación usando la API que proporciona ETERLOGIC.COM©

Para eso tenemos el siguiente código en Delphi

function CrearPuertos(Puertos: String): Boolean;
var
  i: Integer;
  Str: String;
  Id: Integer;
  Module: HModule;
  vspe_activate: function (key: PChar): BOOL; cdecl;
  vspe_initialize: function: BOOL; cdecl;
  vspe_destroyAllDevices: function: BOOL; cdecl;
  vspe_startEmulation: function: BOOL; cdecl;
  vspe_stopEmulation: function: BOOL; cdecl;
  vspe_release: procedure; cdecl;
  vspe_createDevice: function (name, initString: PChar): Integer; cdecl;
begin
  Result:= FALSE;
  Module:= LoadLibrary('VSPE_API.dll');
  if Module <> 0 then
  try
    vspe_activate:= GetProcAddress(Module,'vspe_activate');
    vspe_initialize:= GetProcAddress(Module,'vspe_initialize');
    vspe_destroyAllDevices:= GetProcAddress(Module,'vspe_destroyAllDevices');
    vspe_startEmulation:= GetProcAddress(Module,'vspe_startEmulation');
    vspe_stopEmulation:= GetProcAddress(Module,'vspe_stopEmulation');
    vspe_release:= GetProcAddress(Module,'vspe_release');
    vspe_createDevice:= GetProcAddress(Module,'vspe_createDevice');
    if (@vspe_activate = nil) or  (@vspe_initialize = nil) or
      (@vspe_destroyAllDevices = nil) or (@vspe_startEmulation = nil) or
      (@vspe_stopEmulation = nil) or (@vspe_release = nil) or
      (@vspe_createDevice = nil) then
    begin
      Exit;
    end;
    with TStringList.Create do
    try
      try
        LoadFromFile(IncludeTrailingPathDelimiter(
          ExtractFilePath(ParamStr(0))) + 'vspe_key.txt');
      except
        Exit;
      end;
      if not vspe_activate(PChar(Trim(Text))) then
      begin
        Exit;
      end;
      if not vspe_initialize() then
      begin
        Exit;
      end;
      try
        vspe_destroyAllDevices();
        if not vspe_stopEmulation() then
        begin
          Exit;
        end;
        StrictDelimiter:= TRUE;
        Delimiter:= ',';
        Quotechar:= '"';
        DelimitedText:= Puertos;
        for i:= 0 to Count - 1 do
        begin
          Str:= Trim(Strings[i]);
          if (Str <> EmptyStr) and TryStrToInt(Str,Id) then
          begin
            Id:= vspe_createDevice('Connector',PChar(Str + ';0'));
            if Id = -1 then
            begin
              vspe_destroyAllDevices();
              Exit;
            end;
          end;
        end;
        Result:= vspe_startEmulation();
        if not Result then
        begin
          vspe_destroyAllDevices();
        end;
      finally
        vspe_release();
      end;
    finally
      Free;
    end;
  finally
    FreeLibrary(Module);
  end;
end;
 
// Ejemplo de uso, crea los puertos COM10, COM11 y COM12
CrearPuertos('10,11,12');

Esta función asume varias cosas:

  • Que esta situado en la misma carpeta que la librería VSPE_API.DLL
  • Que en la misma carpeta existe un fichero llamado "vspe_key.txt" que contiene la API KEY que viene en el mismo zip que el programa de instalación (solo la linea con la clave no el resto del texto)

Enlaces:
http://www.eterlogic.com/Products.VSPE.html

Enviar un comentario nuevo

El contenido de este campo se mantiene privado y no se mostrará públicamente.