3
votes

My Delphi XE6 project needs to call SOAP-based webservices. Unfortunately it seems that there may be a problem performing such webservice calls from 64-bit DLLs under IIS, which is how my project will be deployed.

See for example the following public webservice:

http://www.webservicex.net/geoipservice.asmx?WSDL

After creating a test ISAPI webserver project and importing the WSDL above, I tried using the following code to make a webservice call:

uses activeX, geoipservice;

procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
  CountryName : string;
  I : GeoIPServiceSoap;
  G : GeoIP2;
begin
  CoInitialize(nil);
  try
    CountryName := 'unassigned';
    I := GetGeoIPServiceSoap();
    if assigned(I) then begin
      G := I.GetGeoIP('...insert IP address here...');
      if assigned(G) then begin
        countryname := G.CountryName;
      end;
    end;
    Response.Content :=
      '<html>' +
      '<head><title>Web Service Test</title></head>' +
      '<body>Country: ' + CountryName + '</body>' +
      '</html>';
  except
    on E : exception do begin
      Response.Content :=
        '<html>' +
        '<head><title>Web Service Test</title></head>' +
        '<body>Exception: ' + E.ClassName() + ' ' + E.Message + '</body>' +
        '</html>';
    end;
  end;
  CoUninitialize();
end;

When I run the project as a 32-bit ISAPI DLL, viewing the website in a browser results in a country name being displayed as expected. When I run the project as a 64-bit ISAPI DLL, viewing the website in a browser results in the following error message being displayed (Zugriffsverletzung = access violation):

Exception: EAccessViolation Zugriffsverletzung bei Adresse 000000C700492460. Schreiben von Adresse 000000C700492460

This seems very similar to the following problem:

Delphi XE2 64 bit ISAPI Access Violation

However the problem there relates to Delphi XE2, and it is stated that upgrading to Delphi XE4 fixed the problem. I have tested in both Delphi XE4 and XE6 and the problem occurs in both.

Has anybody else encountered this problem or has an idea how to solve it?

Setup: Delphi XE6, Win8.1, IIS 8.5

1
do you have the problem when you do the webservice calls from a 64bit console application?whosrdaddy
Thanks for the reply. I just tried creating a console webserver application in Delphi XE6, pasted in the above code and compiled the project as a 64-bit EXE. The country name is displayed when viewing the website (no access violation).Tim
I just tried creating a DLL project (not a webserver), from which i export a function which performs the above webservice call. When i call this function from a 64-bit EXE, the country name is returned and no access violation occurs. So the problem presumably relates somehow to Delphi's ISAPI implementation rather than Delphi 64-bit DLLs in general...Tim
So i went ahead and tried the obvious solution of performing the webservice calls in a non-ISAPI 64-bit Delphi DLL, and then calling that DLL from my ISAPI 64-bit Delphi DLL. When i do that, however, the access violation does occur. So it seems that the problem relates to performing webservice calls in a 64-bit DLL running in the context of IIS -- maybe Delphi's webservice calling code is doing something that is not "allowed" by IIS?Tim

1 Answers

0
votes

I believe the problem is related to wininet. Delphi uses Wininet (Via HTTPRIO) to connect to SOAP Servers (see Soap.SOAPHTTPTrans.pas). But Microsoft says that using Wininet inside a service (such as IIS) is not supported, that's why it works on a console application. Services should use WinHTTP. https://support.microsoft.com/en-us/help/238425/info-wininet-not-supported-for-use-in-services

I had the same problem and tried to convert the Wininet calls to WinHTTP, but in the end I gave up on Delphi for this use case, too much trouble for such an expensive tool.