Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Runtime Error 179 in Fortran-DLL

fobermaier
Beginner
1,430 Views
Hello, I have two questions:
the following function works fine within plain fortran programs. Since I need its functionality within a VB6 Application I tried to put it in a DLL-Project but it doesn't work, I get Runtime-Error 179: Cannot allocate array - overflow on array size calculation Cannot allocate array - overflow on array size calculation
This leads to the second Qquestion. The value of iPrim is supposed to be 100003. Initially the return type of thefunction was declared as
type (T_HASHTABLE), pointer
but by doing this the Value of iPrim was different from (much bigger) then 100003. So I changed the return value to Integer(4) and want to return the address of the pointer instead. The value of iPrim is what it is supposed to now, but the error remains the same.
Is it possible to work with the initial decalaration?
!type(T_HASHTABLE) function HashTableInit(iPrim)
integer(4) function HashTableInit(iPrim)
!DEC$ ATTRIBUTES DLLEXPORT
!DEC$ ALIAS: 'HashTableInit'::HashTableInit
use hashtable !DefinesT_HASHTABLE
implicit none
!pointer::HashTableInit
integer(4), intent(in)::iPrim

type(T_HASHTABLE), pointer::ht
integer(4)::i
allocate( ht )
ht%iPrim = iPrim
allocate( ht%hts(0:iPrim-1 ) )
do i = 0, ht%iPrim - 1
ht%hts( i )%iCount = 0
nullify( ht%hts( i )%hiRoot )
end do
!HashTableInit => ht
HashTableInit = loc(ht)

end function
Here is the VisualBasic declaration:
Public Declare Function HashTableInit Lib _
"v3hash.dll" (ByRef iPrim As Long) As Long
I'm using CVF6.6 and VB6 Sp6
Thanks in advance
Felix Obermaier
0 Kudos
4 Replies
Jugoslav_Dujic
Valued Contributor II
1,430 Views
I don't think the error 179 is related with difference in declarations. The error says that run-time library cannot find a contiguous block of memory on the heap whose size is >= 100003*sizeof(ht%hts(1)). Depending on declaration of TYPE hts, this can be fairly huge (what's sizeof(hts) in bytes). Have you tried reducing iPrim.
Re return values, the code looks OK. Speaking in C terms,
- Fortran function returning LOC(TYPE(Foo)) is of type Foo*
- Fortran function returning TYPE(Foo), POINTERis of type Foo**
- Fortran function returning TYPE(Foo) -- I'm not surewhat's correct.
Jugoslav
0 Kudos
fobermaier
Beginner
1,430 Views

Hello Jugoslav,

thanks for your reply.

Unfortunately the VB-Declarationpointed to a wrong DLL.

The function declarationas Integer(4) works now, but the one with type(T_HASHTABLE), Pointer still keeps producing the error 179. In this case iPrim =1475447638 instead of 100003.

I can stick to the Integer(4) definition, but since I need the Hashtable as an argument for other functions I'd like some help on how to adapt function declarations like the following

type(T_HAbiatchEM) function Habiatchem( htTable, iKey, iIndex )
pointer :: Habiatchem
type (T_HASHTABLE), pointer :: htTable
integer(8) :: iKey
integer(4) :: iIndex

...

end function

Can I work with Cray-Style Pointers inside the function?

Thanks in advance
Felix Obermaier
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,430 Views
If you stick with INTEGER(4) definition, the problem is that you cannot ever
DEALLOCATE(ht) itself. You can deallocate ht%hts though, which is the most of the memory, but that leads to a memory leak.
Still, I don't see what iPrim argument has to do with it. Any chance there is a ByRef/ByVal confusion?
Now, I performed a quick test, and it seems that what I said above is not true. Namely, the function with the prototype:
function Foo(iPrim) result (pFoo)
use dfwin
type(T_DEVMODE), pointer:: pFoo
integer:: iPrim
allocate(pFoo)
end function Foo
where you can put anything as T_DEVMODE does not have C equivalent of
T_DEVMODE** __stdcall FOO(int*)
but instead
void FOO(int*, T_DEVMODE**) (or reverse order of args, I didn't check)
that is, FUNCTIONs with non-trivial results in fact end up as SUBROUTINEs where the pointer itself is a stack entry. I assume you did not get import errors in that case because you ALIASed HashTableInit to something other than _HASHTABLEINIT@8, right?
Thus, to have a FUNCTION returning POINTER called correctly, the VB equivalent should be:
Declare SubHashTableInit(ByRef iPrim As Long, ByRef Address As Long)
etc.
(try it with arguments reversed as well, I didn't test).
Note that "Address" argument above will contain address of pointer itself, e.g. if it contains 0xABCD1234, and if that locationcontains value0x12345678, you will find the first member of ht at address 0x12345678. If any fortran functions has non-pointer argument of type T_HASHTABLE, you have to take care about it on VB side (I don't know how to "dereference" a pointer in VB, like Cray in Fortran).
Jugoslav
0 Kudos
fobermaier
Beginner
1,430 Views

thanks a lot, that solved the problem.

Just for your information the declaration is supposed to be the other way around.

void FOO( T_DEVMODE**, int* )

Felix Obermaier
0 Kudos
Reply