MSXML2.ServerXMLHTTP后期绑定"发送" BSTR失败的方法"参数不正确"

时间:2014-10-16 07:46:37

标签: delphi delphi-7 msxml delphi-5 serverxmlhttp

MSXML2.ServerXMLHTTP / MSXML2.XMLHTTP.3.0我的行为非常奇怪 问题出在send方法上。可接受BSTR / SAFEARRAY / XMLDOC对象/ IStream

此代码正常工作很好并且工作多年FServiceUrl, FReqXML命名的用法是有意的)

procedure PostRequest(const FServiceUrl, FReqXML: WideString);
var
  xmlHttp: OleVariant;
begin
  xmlHttp := CreateOleObject('MSXML2.ServerXMLHTTP.6.0');
  xmlHttp.Open('POST', FServiceUrl, False);
  // VarType(FReqXML) -> BSTR
  xmlHttp.send(FReqXML); 
end;

现在我需要将这个过程包装成一个简单的类:

type
  TXMLHttpNet = class
  private
    FServiceUrl: WideString;
    FReqXML: WideString;        
  public
    constructor Create(const AServiceUrl, AReqXML: WideString);
    procedure PostRequest;
  end;

constructor TXMLHttpNet.Create(const AServiceUrl, AReqXML: WideString);
begin
  FServiceUrl := AServiceUrl;
  FReqXML := AReqXML;
end;

procedure TXMLHttpNet.PostRequest; // Problem is in this call
var
  xmlHttp: OleVariant;
begin
  xmlHttp := CreateOleObject('MSXML2.ServerXMLHTTP.6.0');
  xmlHttp.Open('POST', FServiceUrl, False);
  // VarType(FReqXML) -> BSTR
  xmlHttp.send(FReqXML); // EOleException: "the parameter is incorrect"
end;

奇怪的是,上面一行xmlHttp.send(FReqXML);引发了一个异常:

  

EOleException:“参数不正确”

请注意FReqXML类型在两种情况下都相同(WideString/BSTR

一个简单的测试:

uses ComObj;

procedure TForm1.Button1Click(Sender: TObject);
var
  Request: TXMLHttpNet;
begin
  // simple procedure
  PostRequest('http://www.gmail.com', 'foo'); // OK!
  // via object method
  Request := TXMLHttpNet.Create('http://www.gmail.com', 'foo'); 
  Request.PostRequest; // EOleException: "the parameter is incorrect"
  Request.Free;
end;

我根本无法理解为什么会发生这种异常!

如果我在FReqXML中使用WideString明确地将VarToWideStr“转换为TXMLHttpNet.PostRequest,那就可以了:

xmlHttp.send(VarToWideStr(FReqXML));

甚至奇怪地喜欢这个(!):

xmlHttp.send((FReqXML)); // note the double Brackets

问题:这里发生了什么? 我可以告诉FReqXML在两种情况下都是 WideString/BSTR 为什么FReqXML参数在两种情况下表现不同?

1 个答案:

答案 0 :(得分:1)

你是对的,FReqXML在两种情况下属于同一类型,但在后一种情况下,其内存是根据对象的内存(堆)分配的。根据Delphi版本和编译器设置,这可能会导致用于字符串的内存的行为不同于仅限本地使用(堆栈)。这就是VarToWideStr确实起作用的原因(而且显然还有一些奇怪的额外括号)。

除此之外,我强烈建议导入MSXML2类型库并使用它。它使用早期绑定,这不仅提高了性能,还在代码编辑器中启用了代码完成。

您可以使用类型库导入程序生成它,或使用我拥有here的副本。

然后,请勿使用OleVariantCreateOleObject(导致后期绑定),但请使用CoServerXMLHTTP.CreateXMLHTTP接口类型。

相关问题