Ian*_*oyd 8 delphi ado delphi-xe6
我试图在XE6中使用断开连接的ADO Recordset.这个想法是你正常打开记录集,然后你将记录集的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);
Run Code Online (Sandbox Code Playgroud)
问题是我无法在Delphi XE6中使用它.在Delphi 5中我会成功致电:
rs.Set_ActiveConnection(nil);
Run Code Online (Sandbox Code Playgroud)
一切都很出色.它起作用,因为_Recordset接口被声明为:
procedure Set_ActiveConnection(const pvar: IDispatch); safecall;
Run Code Online (Sandbox Code Playgroud)
所以通过是有效的nil; 它起作用了.
在XE6中,退出变为:
procedure Set_ActiveConnection(pvar: OleVariant); safecall;
Run Code Online (Sandbox Code Playgroud)
你不能通过nil.那么问题就变成了,OleVariant相当于nil什么?
//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(nil); //E2010 Incompatible types: 'OleVariant' and 'Pointer'
Run Code Online (Sandbox Code Playgroud)
//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(Null);
Run Code Online (Sandbox Code Playgroud)
导致异常:
参数类型错误,超出可接受的范围,或彼此冲突
//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(EmptyParam);
Run Code Online (Sandbox Code Playgroud)
导致异常:
参数类型错误,超出可接受的范围,或彼此冲突
//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(Unassigned);
Run Code Online (Sandbox Code Playgroud)
导致异常:
参数类型错误,超出可接受的范围,或彼此冲突
//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(OleVariant(nil)); //E2089 Invalid typecast
Run Code Online (Sandbox Code Playgroud)
//Disconnect the recordset by setting the .ActiveConnection to null
rs.Set_ActiveConnection(OleVariant(Null));
Run Code Online (Sandbox Code Playgroud)
导致异常:
参数类型错误,超出可接受的范围,或彼此冲突
我很清楚,Codebarcadero的声明是错误的.它真的应该是一个IDispatch.这意味着我需要欺骗编译器传递位于地址(即nil)的OleVariant0x00000000.那样ADO会看到0x00000000堆栈上的值,并且我知道我的意思是null:
rs.Set_ActiveConnection(POleVariant(nil)^); //access violation before call
Run Code Online (Sandbox Code Playgroud)
我确定Bo..Imp ...... Co ..Embarcadero有打算调用它的方法; 我只是想不出来.
Dephi 5做的正确; 它将$ 00(即nil)推入堆栈:
rs.Set_ActiveConnection(nil);
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正在经历英勇的努力,做一些我不知道的事情:
rs.Set_ActiveConnection(nil);
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;
Run Code Online (Sandbox Code Playgroud)
在德尔福 XE6 中:
Recordset15 = interface(_ADO)
['{0000050E-0000-0010-8000-00AA006D2EA4}']
//...
procedure _Set_ActiveConnection(const pvar: IDispatch); safecall;
procedure Set_ActiveConnection(pvar: OleVariant); safecall;
Run Code Online (Sandbox Code Playgroud)
所以尝试一下XE6中的其他版本。就我个人而言,我会尝试
Set_ActiveConnection(IDispatch(Nil))
Run Code Online (Sandbox Code Playgroud)
首先,但您在评论中说 _Set_ActiveConnection 适合您。
对于需要传递 OleVariant 的接口,我首先尝试 Set_ActiveConnection(IDispatch(Nil)) 的原因是:自从接口被添加到 Delphi 中(在 D3 中?),iirc 在变体之后的版本中 -添加了基于 OLE 自动化 (D2),编译器知道如何生成代码以在 OleVariant 和 IDispatch 接口之间进行双向转换。所以“问题”是如何将 IDispatch 接口作为 OleVariant 参数传递。从我简单的角度来看,这一点很简单,只需编写 IDispatch() ,其中参数应该是 OleVariant,然后让编译器整理要生成的代码。如果我们想要作为 IDisaptch 接口传递的值实际上是 Nil,我们只需要编写
SomeInterfaceMemberExpectingAnOleVariant(IDispatch(Nil))
Run Code Online (Sandbox Code Playgroud)