title: SOAP Web Service Client in Borland C++ Builder 6
body: <p>Here below is the step-by-step attempt to developp a Web Service client in an application developped in Borland C++ Builder 6.
  Help is welcome to correct this code or to suggest any other solution (though I now try to use a dll developped in C++ Builder XE3).
  Here is my attempt to use Soap in Borland 6 C++ Builder. Untill now I conclude that I cannot succeed because Borland 6 does not manage SOAP header (absent of InvokeRegistry.hpp) and the SOAP server to whom we send requests needs cookies to be passed after the login of this interface :</p>
  
  <pre><code>    __interface INTERFACE_UUID("{B0F412ED-AC6A-42C3-8730-DD0D9680F16D}") AuthenticationSoap : public IInvokable
      {
      public:
        virtual LoginResult*    Login(const AnsiString username, const AnsiString password) = 0; 
        virtual AuthenticationMode Mode() = 0; 
      };
      typedef DelphiInterface&lt;AuthenticationSoap&gt; _di_AuthenticationSoap;
  </code></pre>
  
  <p>this login first sends a :</p>
  
  <pre><code>    500 Server Internal Error
  </code></pre>
  
  <p>then is ok if I add this call :</p>
  
  <pre><code>    InvRegistry()-&gt;RegisterInvokeOptions(__interfaceTypeinfo(AuthenticationSoap), ioDocument);
  </code></pre>
  
  <p>then I pass the User Name to a HTTPRIO :</p>
  
  <pre><code>    MyHTTPRIO-&gt;HTTPWebNode-&gt;UserName = AnsiString("xxx...");
  </code></pre>
  
  <p>And this HTTPRIO is passed to the second interface :</p>
  
  <pre><code>    __interface INTERFACE_UUID("{1E5B3820-A40E-FD40-326D-95A9F6B7A5F0}") OrganizerWS_1_1Soap : public IInvokable
      {
      public:
      ...
      virtual void            findHorse(const ArrayOfString FEIIDs, const AnsiString Name, const AnsiString SexCode, const bool IsPony, const AnsiString AthleteFEIID, ArrayOfHorseOC&amp; findHorseResult, ArrayOfMessage&amp; Messages) = 0;
      ...
      };
      typedef DelphiInterface&lt;OrganizerWS_1_1Soap&gt; _di_OrganizerWS_1_1Soap;
      _di_OrganizerWS_1_1Soap GetOrganizerWS_1_1Soap(bool useWSDL=false, AnsiString addr="", Soaphttpclient::THTTPRIO* HTTPRIO=0);
  </code></pre>
  
  <p>But we get an error "AuthHeader is missing" because we have used Borland 6's WSDL importer which does not generates code for Headers and headers are not defined in Invokeregistry.hpp.
  So in the "BeforeExecute" of our HTTPRIO we have this request :</p>
  
  <pre><code>    &lt;?xml version="1.0"?&gt;
      &lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
      &lt;SOAP-ENV:Body&gt;
          &lt;findHorse xmlns="http://fei.org/"&gt;
              &lt;FEIIDs/&gt;
              &lt;Name&gt;&lt;/Name&gt;
              &lt;SexCode&gt;&lt;/SexCode&gt;
              &lt;IsPony&gt;false&lt;/IsPony&gt;
              &lt;AthleteFEIID&gt;10002254&lt;/AthleteFEIID&gt;
              &lt;findHorseResult/&gt;
              &lt;Messages/&gt;
          &lt;/findHorse&gt;
      &lt;/SOAP-ENV:Body&gt;
      &lt;/SOAP-ENV:Envelope&gt;
  </code></pre>
  
  <p>whereas Borland XE3 generates this request which is ok and brings the expected response from the server :</p>
  
  <pre><code>    &lt;?xml version="1.0"?&gt;
      &lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
      &lt;SOAP-ENV:Header&gt;
          &lt;NS1:AuthHeader xmlns:NS1="http://fei.org/"&gt;
              &lt;UserName xmlns="http://fei.org/"&gt;xxx...&lt;/UserName&gt;
              &lt;Language xmlns="http://fei.org/"&gt;en&lt;/Language&gt;
          &lt;/NS1:AuthHeader&gt;
      &lt;/SOAP-ENV:Header&gt;
      &lt;SOAP-ENV:Body&gt;
          &lt;findHorse xmlns="http://fei.org/"&gt;
              &lt;IsPony&gt;false&lt;/IsPony&gt;
              &lt;AthleteFEIID&gt;10002254&lt;/AthleteFEIID&gt;
          &lt;/findHorse&gt;
      &lt;/SOAP-ENV:Body&gt;
      &lt;/SOAP-ENV:Envelope&gt;
  </code></pre>
  
  <p>So I first replaced</p>
  
  <pre><code>    &lt;SOAP-ENV:Body&gt;
  </code></pre>
  
  <p>by</p>
  
  <pre><code>    &lt;SOAP-ENV:Header&gt;&lt;NS1:AuthHeader xmlns:NS1="http://fei.org/"&gt;&lt;UserName xmlns="http://fei.org/"&gt;xxx...&lt;/UserName&gt;&lt;Language xmlns="http://fei.org/"&gt;en&lt;/Language&gt;&lt;/NS1:AuthHeader&gt;&lt;/SOAP-ENV:Header&gt;&lt;SOAP-ENV:Body&gt;
  </code></pre>
  
  <p>then added options as for example "&lt;&lt; xoHolderClass &lt;&lt; xoInlineArrays" :</p>
  
  <pre><code>    RemClassRegistry()-&gt;RegisterSerializeOptions(__classid(findHorse), (TSerializationOptions() &lt;&lt; xoHolderClass &lt;&lt; xoInlineArrays));
  </code></pre>
  
  <p>here I obtain the same request but the answer of the server is a NULL array whereas there are three items in the answer to a test written in borland xe3.
  Or with other manipulations (without xo... options) I get access violation in delphi interfaces destructor :</p>
  
  <pre><code>    __fastcall ~DelphiInterface&lt;T&gt;()
        {
              if (intf != 0) 
              {
                intf-&gt;Release();
                intf = 0;
              }
        }
  </code></pre>
  
  <p>I explored other solutions (such as using indySOAP which is available only in Delphi sources (no C++ sources), thought about creating the XML and sending with Indy components (but expect I would encounter a same authentication header issue ?), using CAPICOM, or windows SDK ? ...) but without success until now and as said before I now try to use a dll developped in C++ Builder XE3 :
  <a href="https://stackoverflow.com/questions/15485276/embarcadero-c-xe3-dll-imported-in-c-xe3-project-library-loads-but-access-v">https://stackoverflow.com/questions/15485276/embarcadero-c-xe3-dll-imported-in-c-xe3-project-library-loads-but-access-v</a></p>