Search code examples
delphiupnp

How to get the return value of IStaticPortMappingCollection.Add return or not?


I use seattle in windows 10 64 bit.

I try to forward a port by upnp and get the return value. The port forwarding works well but the following line makes 'could not convert variant of type (dispatch) into type (integer)' window.

_hResult := _Ports.add(_PortNumber, 'TCP', _PortNumber, Edit1.Text, True, _PortName); 

You can find the return value type in the following msdn webpage.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366148(v=vs.85).aspx

The whole code is

uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Win.ComObj, Vcl.StdCtrls;

procedure TForm1.FormClick(Sender: TObject);
var
  _NAT: Variant;
  _Ports: Variant;
  _PortNumber: Integer;
  _PortName: string;
  _hResult: HRESULT;
begin
  _NAT := CreateOleObject('hnetcfg.natupnp');
  _Ports := _NAT.staticportmappingcollection;

  _PortNumber := 8000;
  _PortName := 'test';

  if VarIsClear(_Ports) then // $00000000
  begin
    Caption := 'error';
  end
  else
  begin
    _hResult := _Ports.add(_PortNumber, 'TCP', _PortNumber, Edit1.Text, True, _PortName);

    if _hResult = S_OK then
    begin
      Caption := 'succeeded';
    end;
  end;
end;

Solution

  • Ports.Add() returns an IStaticPortMapping interface. So you should write:

    var
      _Port: Variant;
    ....
    _Port := _Ports.Add(..._);
    

    You've been looking at documentation that shows Add returning an HRESULT, and the IStaticPortMapping as an out parameter. But the method has been subject to parameter re-writing. The framework, in the COM method dispatch, does check the actual return value and raise an exception in case of failure. But that is all done in the background.