I have a routine with this prototype in a *.dll
Public Sub RaiseError(ByRef vError As Variant, _
ByVal sRoutine As String, _
ByVal sApplicationVersion As String, _
Optional ByVal sDetail As String =
VBA.Constants.vbNullStrin
'Verifica la congruenza dell'input.
If AndAlso(VBA.ObjPtr(vErrore) <> VBA.ObjPtr(Err), _
Not TypeOf vErrore Is IObjectError) Then
Exit Sub
End If
'Verifica se è necessario segnalare un errore.
If vErrore.number = 0& Then Exit Sub
...
End Sub
In:: vError can be vb6 object Err singleton or an personalized class
that
support my IObjectError interface.
I reference this *.dll from a vb6 project.
I look that if I call this routine from my project and set In:: vError
to Err Object,
when the row VBA.ObjPtr(vErrore) <> VBA.ObjPtr(Err) is execute, my
input variable it is
cleared.
If I comment this row, the routine work fine.
Why, any idea?
Ralph - 27 Mar 2008 14:43 GMT
I have a routine with this prototype in a *.dll
Public Sub RaiseError(ByRef vError As Variant, _
ByVal sRoutine As String, _
ByVal sApplicationVersion As String, _
Optional ByVal sDetail As String =
VBA.Constants.vbNullStrin
'Verifica la congruenza dell'input.
If AndAlso(VBA.ObjPtr(vErrore) <> VBA.ObjPtr(Err), _
Not TypeOf vErrore Is IObjectError) Then
Exit Sub
End If
'Verifica se è necessario segnalare un errore.
If vErrore.number = 0& Then Exit Sub
...
End Sub
In:: vError can be vb6 object Err singleton or an personalized class
that
support my IObjectError interface.
I reference this *.dll from a vb6 project.
I look that if I call this routine from my project and set In:: vError
to Err Object,
when the row VBA.ObjPtr(vErrore) <> VBA.ObjPtr(Err) is execute, my
input variable it is
cleared.
If I comment this row, the routine work fine.
Why, any idea?
=================================================
This is not an exact answer for your situation. Consider it more of a
collection of 'hints' (mostly stolen <g>) on how to research the problem
yourself.
"ObjPtr returns the pointer to the interface referenced by an object
variable".
Sounds simple enough, but objects actually support multiple interfaces, and
you may not get the correct interface when looking at the address of an
object. In COM you can retrieve the address of any interface from the
address of another interface in the same coclass. But apparently VB turns
this around on occasion allowing multiple instances/references to the same
interface.
For example, with a VB Declare to find a pointer to a generic object, there
is no way to guarantee that the interface received by the Dll will the same
as the one passed. For example, for a VB6 created Class1:
' Requires a stdole (OLE Automation) reference
Declare Function VBObjPtr Lib "msvbvm50.dll" _
Alias "VarPtr" (ByVal pObj As IUnknown) As Long
Dim oCls As New Class1
' These value will be different:
Debug.Print ObjPtr(oCls), VBObjPtr(oCls)
Heres another thing to play with...
Dim oMy As MyClass
Dim pInterface As MyInterface
Dim pObjCls As Object '--- IDispatch
Dim pObjInt As Object
Dim pUnk As IUnknown
Set oMy = New MyClass
Set pInterface = oMy
Set pObjCls = oMy
Set pObjInt = pInterface
Debug.Print ObjPtr(pObjCls), ObjPtr(pObjInt)
... you will get different references. You can resolve this issue using QI
for
IDispatch from the IUnknown interface this way:
'--- from "second" IDispatch get "first" one
Set pUnk = pObjInt
Set pObjInt = pUnk
Debug.Print ObjPtr(pObjCls), ObjPtr(pObjInt)
In other words the chances of getting an ObjPtr to the *same* object in
different situations to actually be the *same* is just that - a "chance".
<g>
I believe there is more information available in Matt Curland's book
"Advanced VB Programming". Which I heartily recommend for any indepth look
at VB6.
hth
-ralph