gpt4 book ai didi

delphi - 如何在XE6中断开ADO记录集?

转载 作者:行者123 更新时间:2023-12-03 14:48:54 25 4
gpt4 key购买 nike

我正在尝试在 XE6 中使用断开连接的 ADO 记录集。这个想法是,您正常打开记录集,然后将记录集的 ActiveConnection 设置为您语言的等效值 null/Nothing/nil :

rs.Set_ActiveConnection(null);

以下来自 Delphi 5 的示例运行良好:

var rs: _Recordset;

rs := CoRecordset.Create;
rs.CursorLocation := adUseClient; //the default for a Recordset is adUseServer (Connection.Execute's default is adUseClient)
rs.CursorType := adOpenForwardOnly; //the default
rs.Open(CommandText, Conn,
adOpenForwardOnly, //CursorType
adLockReadOnly, //LockType
adCmdText);

//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(nil);

它适用于 Delphi 5

问题是我无法使其在 Delphi XE6 中工作。在 Delphi 5 中我会成功调用:

rs.Set_ActiveConnection(nil);

一切都很顺利。它之所以有效,是因为 _Recordset接口(interface)声明为:

procedure Set_ActiveConnection(const pvar: IDispatch); safecall;

所以通过 nil 是有效的;它起作用了。

在 XE6 中,声明更改为:

procedure Set_ActiveConnection(pvar: OleVariant); safecall;

您无法传递 nil 。那么问题就变成了,OleVariant 是什么?相当于 nil

尝试#1

//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(nil); //E2010 Incompatible types: 'OleVariant' and 'Pointer'

尝试#2

//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(Null);

导致异常:

Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another

尝试#3

//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(EmptyParam);

导致异常:

Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another

尝试#4

//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(Unassigned);

导致异常:

Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another

尝试#5

//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(OleVariant(nil)); //E2089 Invalid typecast

尝试#6

//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(OleVariant(Null));

导致异常:

Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another

尝试#7

我很清楚 Codebarcadero 的声明是错误的。它确实应该是 IDispatch 。这意味着我需要欺骗编译器传递位于地址 0x00000000OleVariant (即零)。这样 ADO 将看到值 0x00000000在堆栈上,知道我的意思是 null :

rs.Set_ActiveConnection(POleVariant(nil)^); //access violation before call

我确信 Bo..Imp...Co..Embarcadero 有指定的方式来调用它;我就是想不通。

德尔福5汇编

Dephi 5 做了正确的事情;它将 $00 (即 nil )压入堆栈:

<strong>rs.Set_ActiveConnection(nil);</strong>
push $0 ;push nil
mov eax,[ebp-$08] ;get address of rs
push eax ;push "this"
mov eax,[eax] ;get VMT of IRecordset
call dword ptr [eax+$28] ;call offset $28 of VMT

而 Delphi XE6 正在通过英勇的努力去做一些我不知道的事情:

<strong>rs.Set_ActiveConnection(nil);</strong>
lea eax,[ebp-$000000d8]
call Null
lea edx,[ebp-$000000d8]
lea eax,[ebp-$000000c8]
call @OleVarFromVar
push dword ptr [ebp-$000000bc]
push dword ptr [ebp-$000000c0]
push dword ptr [ebp-$000000c4]
push dword ptr [ebp-$000000c8]
mov eax,[ebp-$04]
push eax
mov eax,[eax]
call dword ptr [eax+$2c]

奖励阅读

最佳答案

在 D7 中(手头没有 D5),AdoInt.Pas 包含两种类型的 Set_ActiveConnection,例如

  Recordset15 = interface(_ADO)
['{0000050E-0000-0010-8000-00AA006D2EA4}']
procedure Set_ActiveConnection(const pvar: IDispatch); safecall;
procedure _Set_ActiveConnection(pvar: OleVariant); safecall;

在 Delphi XE6 中:

Recordset15 = interface(_ADO)
['{0000050E-0000-0010-8000-00AA006D2EA4}']
//...
procedure _Set_ActiveConnection(const pvar: IDispatch); safecall;
procedure Set_ActiveConnection(pvar: OleVariant); safecall;

所以尝试XE6中的其他版本。就我个人而言,我会尝试

Set_ActiveConnection(IDispatch(Nil)) 

首先,但您在评论中说 _Set_ActiveConnection 适合您。

对于需要传递 OleVariant 的接口(interface),我首先尝试 Set_ActiveConnection(IDispatch(Nil)) 的原因是:自从接口(interface)被添加到 Delphi 中(在 D3 中?),版本中的 iirc添加基于变体的 OLE 自动化 (D2) 后,编译器知道如何生成代码以在 OleVariant 和 IDispatch 接口(interface)之间进行双向转换。所以“问题”是如何将 IDispatch 接口(interface)作为 OleVariant 参数传递。从我简单的角度来看,这一点很简单,只需编写 IDispatch() ,其中参数应该是 OleVariant,然后让编译器整理要生成的代码。如果我们想要作为 IDisaptch 接口(interface)传递的实际上是 Nil,我们只需要编写

SomeInterfaceMemberExpectingAnOleVariant(IDispatch(Nil))

关于delphi - 如何在XE6中断开ADO记录集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32017376/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com