Microsoft KB Archive/195049

= How To Maintain Binary Compatibility in Components Exposing ADO =

Article ID: 195049

Article Last Modified on 3/14/2005

-

APPLIES TO


 * Microsoft Data Access Components 1.5
 * Microsoft Data Access Components 2.0
 * Microsoft Data Access Components 2.1 Service Pack 2
 * Microsoft Data Access Components 2.5
 * Microsoft Data Access Components 2.6
 * Microsoft Data Access Components 2.7
 * Microsoft Visual Basic 5.0 Enterprise Edition
 * Microsoft Visual Basic 6.0 Enterprise Edition

-



This article was previously published under Q195049



SUMMARY
Recompiling a Visual Basic Project that uses Binary Compatibility can generate a warning to the following effect:

"...module has arguments and/or return type that is incompatible with a similar declaration in the version compatible component. ... Original Definition: Function  as ADODB.Recordset15 Current Definition: Function  as ADODB.Recordset ..."

The dialog box offers a choice to either accept and break the compatibility or edit and preserve the return types or arguments. Alternatively, you may see the following error:

Compile Error: Procedure declaration does not match description of event or procedure having the same name.

These errors occur because the component, now being compiled with a later version of ActiveX Data Objects (ADO), is exposing objects such as a Recordset and is attempting to maintain Binary Compatibility with the component compiled with an earlier version of ADO. This behavior is by design.



MORE INFORMATION
Visual Basic code makes use of Version Independent ProgIDs such as "ADODB.Recordset". This Version Independent ProgID is then used to obtain a Class ID for that particular class when you compile the project. Under ADO 1.5, for example, the Version Independent ProgIDs mapped to the ADO 1.5 Interface ClsIDs. When you attempt to recompile a component with a later version of ADO, the Version Independent ProgIDs now map to the later Interface ClsIDs. For example, ADO and later Interfaces are not Binary Compatible with the ADO 1.5 interfaces.

To make the component Binary Compatible with Clients expecting an earlier interface, make the ADO interface(s) exposed version-specific.

For example, change the function declaration from a version independent declaration: Function  as ADODB.Recordset to a version specific declaration: Function  as ADODB.[_Recordset15] There is a previous version specific ProgID exposed for each of the main ADO objects, Recordset, Command, and Connection.

To specify a version specific declaration, append the version identifier to the ADO object: ByVal pRecordset As ADODB.Recordset20 Note: Under ADO 2.0, objects were prefaced with an underscore, postfixed with a version identifier and enclosed in square brackets.

After modifying the declarations, the project compiles without the Binary Compatibility warning.

Following is a more complete example of taking the ADO code to a later version of ADO while maintaining binary compatibility with the earlier version. The following example is an ADO method that returns an ADO RecordSet object.

If this function was compiled under ADO 1.5, you would have to modify the function declaration so that it would maintain binary compatibility with ADO 1.5. Public Function ReturnRS(strConnect As String, _                           strQuery As String) As ADODB.Recordset Dim adoCon1 As New ADODB.Connection Dim adoRs1 As New ADODB.Recordset

' Set the CursorLocation to adUseClient to return an ADORecordset. adoCon1.CursorLocation = adUseClient

' Open ADO Connection with passed in connect string. adoCon1.Open strConnect

' Open ADO Recordset with passed in SQL string. adoRs1.Open strQuery, adoCon1, adOpenKeyset, adLockBatchOptimistic

' Return ADO Recordset object to Client. Set ReturnRS = adoRs1

' Can not close the ADO Recordset object here, ' but it can be disassociated. Set adoRs1.ActiveConnection = Nothing

' Close ADO Connection object. adoCon1.Close

End Function Here is the same function modified so that when compiled with a later version of ADO, it maintains binary compatibility with ADO 1.5: Public Function ReturnRS(strConnect As String, _                        strQuery As String) As ADODB.Recordset15

' Or, Use this syntax for ADO 2.0 ' Public Function ReturnRS(strConnect As String, _                        ' strQuery As String) As ADODB.[_Recordset15] Dim adoCon1 As New ADODB.Connection Dim adoRs1 As New ADODB.Recordset

' Set the CursorLocation to adUseClient to return an ADORecordset. adoCon1.CursorLocation = adUseClient

' Open ADO Connection with passed in connect string. adoCon1.Open strConnect

' Open ADO Recordset with passed in SQL string. adoRs1.Open strQuery, adoCon1, adOpenKeyset, adLockBatchOptimistic

' Return ADO Recordset object to Client. Set ReturnRS = adoRs1

' Can not close the ADO Recordset object here, ' but it can be disassociated. Set adoRs1.ActiveConnection = Nothing

' Close ADO Connection object. adoCon1.Close

End Function The component or application that you compile against the later version of ADO requires the later components to run successfully even if your component or application only exposes the earlier interfaces. This is common practice when compiling with dependencies. If you recompile a component with a newer version of a dependency, the newer dependency becomes a baseline for the resulting component and you need to redistribute the newer dependency file with the component. This is no different than recompiling a Visual Basic application under a newer version of Visual Basic. The resulting application will not run if you do not distribute the new Visual Basic run- time .dll with the application.

The benefit of this implementation in Visual Basic is that the code can take advantage of the new features and benefits of a new version of ADO and still remain binary compatible with clients expecting the earlier interfaces.

