Re: SafeArrays problem between Fortran and VB .Net
- From: "Jugoslav Dujic" <jdujic@xxxxxxxxx>
- Date: Wed, 7 Dec 2005 14:18:09 +0100
| Hello, Group,
|
| I have recently been working with VB .Net and now (after a ~20 year
| hiatus) I am again doing some work with Fortran. (I notice things have
| changed a bit.) Anyway, I am in far over my head, and am hoping someone
| will be able to throw me a life-line.
|
| I have a routine in a Fortran DLL that is invoked by a VB .Net method.
| The VB method passes in a reference to a call-back routine that is
| intended to provide data to the Fortran procedure. This technique seems
| to work quite well provided I am only passing simple values back and
| forth. However, I want to be able to pass arrays and I am having some
| challenges with this.
Summary:
| Public Function TestInterface(ByVal strRequest As String, _
| ByVal intRequestLength As Integer, _
| ByRef intData() As Integer) As Integer
| Interface
| Integer Function SSData(strRequest, intData)
| Integer, Pointer :: intData
| Character*10 strRequest
| End Function SSData
| End Interface
| Integer, Pointer :: iptUnits
| iptUnits = SafeArrayCreate(VT_I4, 1, bounddef(0))
| WRITE (1,*) 'SSData = ', SSData(strAction, iptUnits)
By declaring that intData is an Integer, POINTER:: you tell the
compiler to pass a (C-speaking) SAFEARRAY**, but TestInterface
probably expects a SAFEARRAY*.
Another thing that bugs me (I don't have DVF 5.0) is that
INTERFACE of SafeArrayCreate (in CVF6.6C) declares return value
INTEGER(4), not INTEGER(4), POINTER. Thus, you're messing with
memory from the start.
Now, looking in MSDN, SafeArrayCreate returns a SAFEARRAY*.
That means that, in CVF interpretation, its return value is
something opaque (but containing the address of a safearray).
So, try something along these lines:
Interface
Integer Function SSData(strRequest, intData)
!DEC$ATTRIBUTES VALUE:: intData
Integer:: intData
Character*10 strRequest
End Function SSData
End Interface
INTEGER:: iptUnits
iptUnits = SafeArrayCreate(...)
WRITE (1,*) 'SSData = ', SSData(strAction, iptUnits)
I'm not sure whether !DEC$ATTRIBUTES VALUE:: intData is required,
but on the first sight it compensates one level of indirection.
| The problem is, that when the call-back (SSData) is invoked, VB returns
| an error. The message is:
|
| "Safe array of rank 65048 has been passed to
| a method expecting an array of rank 1."
|
| The contents of the log file at this point are:
|
| In Tester: Count = 1
| In Tester: iptUnits = 1900056
| Array count = 1
| Array dims = 1
|
| The value 65048 is hex FE18 and the value 1900056 is hex 1CFE18.
| Perhaps this is just coincidence, but it looks to me as if there is some
| misalignment that is causing part of the array pointer to be interpreted
| as the rank.
That seems plausible, but I don't think it's misalignment, but a
pointer/value/reference mixup overall. Note that
typedef struct FARSTRUCT tagSAFEARRAY {
unsigned short cDims; // Count of dimensions in this array.
unsigned short fFeatures; // Flags used by the SafeArray
// routines documented below.
cDims is 2-byte dimension count, and FE18 is loword of iptUnits. That
matches pretty well, doesn't it? -- you're not passing the SAFEARRAY
by reference, but an address of something instead.
--
Jugoslav
___________
www.xeffort.com
Please reply to the newsgroup.
You can find my real e-mail on my home page above.
.
- Follow-Ups:
- Re: SafeArrays problem between Fortran and VB .Net
- From: R. MacDonald
- Re: SafeArrays problem between Fortran and VB .Net
- References:
- SafeArrays problem between Fortran and VB .Net
- From: R. MacDonald
- SafeArrays problem between Fortran and VB .Net
- Prev by Date: Re: EQUIVALENCE(variable inside module, variable outside module) ????
- Next by Date: Re: SafeArrays problem between Fortran and VB .Net
- Previous by thread: SafeArrays problem between Fortran and VB .Net
- Next by thread: Re: SafeArrays problem between Fortran and VB .Net
- Index(es):
Relevant Pages
|