1

下面是在 Borland C++ Builder 6 开发的应用程序中开发 Web 服务客户端的分步尝试。欢迎帮助更正此代码或建议任何其他解决方案(尽管我现在尝试使用开发的 dll C++ 生成器 XE3)。这是我在 Borland 6 C++ Builder 中使用 Soap 的尝试。直到现在我得出的结论是我不能成功,因为 Borland 6 不管理 SOAP 标头(没有 InvokeRegistry.hpp)并且我们发送请求的 SOAP 服务器需要在登录此接口后传递 cookie:

    __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<AuthenticationSoap> _di_AuthenticationSoap;

此登录首先发送一个:

    500 Server Internal Error

那么如果我添加这个调用就可以了:

    InvRegistry()->RegisterInvokeOptions(__interfaceTypeinfo(AuthenticationSoap), ioDocument);

然后我将用户名传递给 HTTPRIO :

    MyHTTPRIO->HTTPWebNode->UserName = AnsiString("xxx...");

这个 HTTPRIO 被传递到第二个接口:

    __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& findHorseResult, ArrayOfMessage& Messages) = 0;
    ...
    };
    typedef DelphiInterface<OrganizerWS_1_1Soap> _di_OrganizerWS_1_1Soap;
    _di_OrganizerWS_1_1Soap GetOrganizerWS_1_1Soap(bool useWSDL=false, AnsiString addr="", Soaphttpclient::THTTPRIO* HTTPRIO=0);

但是我们得到一个错误“AuthHeader is missing”,因为我们使用了 Borland 6 的 WSDL 导入器,它不会为标头生成代码,并且标头未在 Invokeregistry.hpp 中定义。所以在我们 HTTPRIO 的“BeforeExecute”中,我们有这个请求:

    <?xml version="1.0"?>
    <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">
    <SOAP-ENV:Body>
        <findHorse xmlns="http://fei.org/">
            <FEIIDs/>
            <Name></Name>
            <SexCode></SexCode>
            <IsPony>false</IsPony>
            <AthleteFEIID>10002254</AthleteFEIID>
            <findHorseResult/>
            <Messages/>
        </findHorse>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

而 Borland XE3 生成的这个请求没问题,并从服务器带来了预期的响应:

    <?xml version="1.0"?>
    <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">
    <SOAP-ENV:Header>
        <NS1:AuthHeader xmlns:NS1="http://fei.org/">
            <UserName xmlns="http://fei.org/">xxx...</UserName>
            <Language xmlns="http://fei.org/">en</Language>
        </NS1:AuthHeader>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <findHorse xmlns="http://fei.org/">
            <IsPony>false</IsPony>
            <AthleteFEIID>10002254</AthleteFEIID>
        </findHorse>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

所以我先换了

    <SOAP-ENV:Body>

经过

    <SOAP-ENV:Header><NS1:AuthHeader xmlns:NS1="http://fei.org/"><UserName xmlns="http://fei.org/">xxx...</UserName><Language xmlns="http://fei.org/">en</Language></NS1:AuthHeader></SOAP-ENV:Header><SOAP-ENV:Body>

然后添加选项,例如 "<< xoHolderClass << xoInlineArrays" :

    RemClassRegistry()->RegisterSerializeOptions(__classid(findHorse), (TSerializationOptions() << xoHolderClass << xoInlineArrays));

在这里,我获得了相同的请求,但服务器的答案是一个 NULL 数组,而用 borland xe3 编写的测试的答案中有三个项目。或者使用其他操作(没有 xo... 选项)我在 delphi 接口析构函数中遇到访问冲突:

    __fastcall ~DelphiInterface<T>()
      {
            if (intf != 0) 
            {
              intf->Release();
              intf = 0;
            }
      }

我探索了其他解决方案(例如使用仅在 Delphi 源(无 C++ 源)中可用的 indySOAP,考虑创建 XML 并使用 Indy 组件发送(但预计我会遇到相同的身份验证标头问题?),使用 CAPICOM,或windows SDK?...)但直到现在都没有成功,正如之前所说,我现在尝试使用在 C++ Builder XE3 中开发的 dll: https ://stackoverflow.com/questions/15485276/embarcadero-c-xe3-dll-imported -in-c-xe3-project-library-loads-but-access-v

4

0 回答 0