- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
I am trying to get to the data in array that is created in a COM application. The interface routine specifies a return argument that is a pointer to a pointer to the data array. Is it even possible to access this data via FORTRAN?
Any ideas?
Any ideas?
Link copiado
4 Respostas
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
Yes it is possible. For best results post the IDL and optionally the C++ prototype. What f90 code did the Module Wizard produce for this routine? (I'd post that too)
-John
-John
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
I can supply the module wizard code, the C++ code is not mine, I'll have to look around for the IDL.
Wizard Code:
INTEGER*4 FUNCTION $IOPCGroup_SyncWrite($OBJECT, NumItems, ServerHandles, Values, Errors)
!DEC$ ATTRIBUTES DLLEXPORT :: $IOPCGroup_SyncWrite
IMPLICIT NONE
INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer
!DEC$ ATTRIBUTES VALUE :: $OBJECT
INTEGER*4, INTENT(IN) :: NumItems
!DEC$ ATTRIBUTES REFERENCE :: NumItems
INTEGER(INT_PTR_KIND()), INTENT(IN) :: ServerHandles ! (SafeArray)
!DEC$ ATTRIBUTES REFERENCE :: ServerHandles
INTEGER(INT_PTR_KIND()), INTENT(IN) :: Values ! (SafeArray)
!DEC$ ATTRIBUTES REFERENCE :: Values
INTEGER(INT_PTR_KIND()), INTENT(OUT) :: Errors ! (SafeArray)
!DEC$ ATTRIBUTES REFERENCE :: Errors
INTEGER*4 $RETURN
INTEGER(INT_PTR_KIND()) $VTBL ! Interface Function Table
POINTER($VPTR, $VTBL)
$VPTR = $OBJECT ! Interface Function Table
$VPTR = $VTBL + 112 ! Add routine table offset
IOPCGroup_SyncWrite_PTR = $VTBL
$RETURN = IOPCGroup_SyncWrite($OBJECT, NumItems, ServerHandles, Values, Errors)
$IOPCGroup_SyncWrite = $RETURN
END FUNCTION $IOPCGroup_SyncWrite
I have tried this using the SAFEARRAY's, it works when run in the debugger, when run outside of the debugger it hangs in above write stmt. If I replace the Errors argument with a I*4 variable and ignore it (ie don't bother checking the values) everything is fine. This is possibly a memory corruption issue (the hang), but it is impossible to locate when everything runs fine in the debugger.
Wizard Code:
INTEGER*4 FUNCTION $IOPCGroup_SyncWrite($OBJECT, NumItems, ServerHandles, Values, Errors)
!DEC$ ATTRIBUTES DLLEXPORT :: $IOPCGroup_SyncWrite
IMPLICIT NONE
INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer
!DEC$ ATTRIBUTES VALUE :: $OBJECT
INTEGER*4, INTENT(IN) :: NumItems
!DEC$ ATTRIBUTES REFERENCE :: NumItems
INTEGER(INT_PTR_KIND()), INTENT(IN) :: ServerHandles ! (SafeArray)
!DEC$ ATTRIBUTES REFERENCE :: ServerHandles
INTEGER(INT_PTR_KIND()), INTENT(IN) :: Values ! (SafeArray)
!DEC$ ATTRIBUTES REFERENCE :: Values
INTEGER(INT_PTR_KIND()), INTENT(OUT) :: Errors ! (SafeArray)
!DEC$ ATTRIBUTES REFERENCE :: Errors
INTEGER*4 $RETURN
INTEGER(INT_PTR_KIND()) $VTBL ! Interface Function Table
POINTER($VPTR, $VTBL)
$VPTR = $OBJECT ! Interface Function Table
$VPTR = $VTBL + 112 ! Add routine table offset
IOPCGroup_SyncWrite_PTR = $VTBL
$RETURN = IOPCGroup_SyncWrite($OBJECT, NumItems, ServerHandles, Values, Errors)
$IOPCGroup_SyncWrite = $RETURN
END FUNCTION $IOPCGroup_SyncWrite
I have tried this using the SAFEARRAY's, it works when run in the debugger, when run outside of the debugger it hangs in above write stmt. If I replace the Errors argument with a I*4 variable and ignore it (ie don't bother checking the values) everything is fine. This is possibly a memory corruption issue (the hang), but it is impossible to locate when everything runs fine in the debugger.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
Errors is an explicit intent out safearray. So I'd bet that the COM method is allocating the memory for it (calling SafeArrayCreate) and passing it out - your description of what happens when you pass an int for Errors supports this too. You need to know this for certain. It is part of the semantic contract of the interface.
In your call to $IOPCGroup_SyncWrite you want ServerHandles and Values to be integer variables that hold pointers to SafeArrays that you have created and initialized. Errors should be an integer variable that you have initialized to some value (zero). On return, Errors should hold a valid pointer to a SafeArray that you could inspect if you'd like to.
If I am inferring properly from your posting, I'd do something like:
hth,
John
In your call to $IOPCGroup_SyncWrite you want ServerHandles and Values to be integer variables that hold pointers to SafeArrays that you have created and initialized. Errors should be an integer variable that you have initialized to some value (zero). On return, Errors should hold a valid pointer to a SafeArray that you could inspect if you'd like to.
If I am inferring properly from your posting, I'd do something like:
! ...
real :: Errors(NumItems) ! if Errors is of type real
pointer (pErrors, Errors)
integer :: psaOut
! ...
psaOut = 0
hr = $IOPCGroup_SyncWrite (pIopcgroup, NumItems, psaHandles, psaValues, psaOut)
if (hr >=0) then
hr = SafeArrayAccessData(psaOut, pErrors)
! examine Errors in here.
hr = SafeArrayUnAccessData(psaOut)
! ...
hth,
John
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
Thanks John, that got it!
Responder
Opções do tópico
- Subscrever fonte RSS
- Marcar tópico como novo
- Marcar tópico como lido
- Flutuar este Tópico para o utilizador atual
- Marcador
- Subscrever
- Página amigável para impressora