Re: SafeArrays problem between Fortran and VB .Net



| 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.
.



Relevant Pages

  • interop: Passing pointer to COM to efficiently receive large data chunk
    ... I'm writing COM to expose some unmanaged imagery generation functions to c#. ... process(SAFEARRAY* bytes) ... does this pass a pointer, or is it marshalled? ... example 2: using fixed array size ...
    (microsoft.public.dotnet.framework.interop)
  • Re: Remove First Row from Variant Array FAST?
    ... >it thinks there is 1 fewer element in the array and incrementing the ... Unlikely you could manipulate the SAFEARRAY construct as you'd like. ... part of the SAFEARRAY structure is the pointer to the data, ... your system with memory leaks by manipulating the pointer directly. ...
    (microsoft.public.excel.programming)
  • Re: Return a pointer from COMs method
    ... pointer to a structure or class. ... Acer Blue ... > Why don't you try SAFEARRAY for returning array of Short ... >> in COM interface? ...
    (microsoft.public.vc.atl)
  • Re: Importing classes from Dll
    ... an interface is not much more than an array of function ... through interface pointer, the compiler calls through function pointer ... But the compiler neatly isolates the boring and tedious parts, ...
    (microsoft.public.vc.language)
  • Re: accessing COM from C# with an IStream** parameter
    ... But as I wrote in my question, I can't change anything at the interface of the C++ COM component. ... ref object arr); ... To pass array in COM, ... Here's some example code on how to retrieve the element in a SAFEARRAY ...
    (microsoft.public.dotnet.languages.csharp)