gpt4 book ai didi

delphi - MSXML2.ServerXMLHTTP 与 BSTR 的后期绑定(bind) "send"方法失败,并显示 "the parameter is incorrect"

转载 作者:行者123 更新时间:2023-12-03 15:58:07 27 4
gpt4 key购买 nike

我的 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: "the parameter is incorrect"

请注意,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;

我根本不明白为什么会发生这个异常!

如果我在 TXMLHttpNet.PostRequest 中使用 VarToWideStr 显式地将 FReqXML“转换”为 WideString ,则可以正常工作:

xmlHttp.send(VarToWideStr(FReqXML));

或者甚至像这样奇怪(!):

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

问题:这里发生了什么?
据我所知,在这两种情况下 FReqXML 都是 WideString/BSTR
为什么 FReqXML 参数在两种情况下的行为不同?

最佳答案

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

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

您可以使用类型库导入器来生成它,或者使用我拥有的副本 here .

然后,不要使用 OleVariantCreateOleObject (这会导致后期绑定(bind)),而是使用 CoServerXMLHTTP.Create XMLHTTP 接口(interface)类型。

关于delphi - MSXML2.ServerXMLHTTP 与 BSTR 的后期绑定(bind) "send"方法失败,并显示 "the parameter is incorrect",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26398912/

27 4 0