下面是在 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