- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We are facing the following problem:
We want to replace a legacy dll previously compiled with CVF with a new version compiled with Intel Fortran. This dll will be called by both new Intel compiled code as well as from legacy CVF code, which we cannot recompile.
Therefore, we want to make the dll with an external interface that is backward compatible with CVF. This generally works fine by specifying
!DEC$ ATTRIBUTESDLLEXPORT,MIXED_STR_LEN_ARG,REFERENCE,STDCALL,ALIAS : 'abc' :: abc
for the new dll routines.
However, this does not seem to work for arrays of strings. The interface for arrays of string in IVF and CVF seem to be handled different.
Below is a sample code to illustrate the problem.
When both executable and dll are compiled with CVF, things work fine, the output is 'abcdefghi'.
When both are compiled by IVF, also both works fine.
When the executable is compiled by CVF and the dll with Intel, it does not work as expected. The output is abcbcdcde. It also doesn't work when the executable is compiled by IVF and the dll with CVF.
It seems likethere is an offset problem here.It seems like the interface for string arrays was changed between CVF and IVF. Is there any way to ensure backward compatability for string arrays?
Any help on this issue would be greatly appreciated. As said before, we cannot change the interface, as there are existing legacy applications compiled with CVF that we cannot recompile.
Btw, this issue is the same for IVF 11.0.61 or IVF 10.1.025.
best regards,
Thomas Boehme
Sample Code:
!===========================================================
! PassingStringArray_prg.f90
program PassingStringArray_prg
USE PassingStringArray_dll
implicit none
! Variables
CHARACTER(LEN=3), DIMENSION(3) :: strarr
! Body
STRARR(1) = 'abc'
STRARR(2) = 'def'
STRARR(3) = 'ghi'
CALL PassingStringArray(strarr)
end program PassingStringArray_prg
!===========================================
! PassingStringArray_dll.f90
MODULE PassingStringArray_dll
CONTAINS
subroutine PassingStringArray(aStringArray)
!DEC$ ATTRIBUTES DLLEXPORT,MIXED_STR_LEN_ARG,REFERENCE,STDCALL,ALIAS : 'PassingStringArray' :: PassingStringArray
implicit none
! Variables
CHARACTER(LEN=*), INTENT(IN) :: aStringArray(:)
! Body
write(*,*) aStringArray
end subroutine PassingStringArray
END MODULE PassingStringArray_dll
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It seems likethere is an offset problem here.It seems like the interface for string arrays was changed between CVF and IVF. Is there any way to ensure backward compatability for string arrays?
CHARACTER(LEN=*), INTENT(IN) :: aStringArray(:)
! Body
You're on partially right track. However, it is not string array interface that was changed, but all assumed-shape (and POINTER and ALLOCATABLE) arrays: Intel has one field more in the array descriptor than CVF.
That being said, I don't have an elegant solution. An obvious workaround of changing aStringArray into assumed-size or explicit-shape array doesn't satisfy your "no interface change" condition.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It seems likethere is an offset problem here.It seems like the interface for string arrays was changed between CVF and IVF. Is there any way to ensure backward compatability for string arrays?
CHARACTER(LEN=*), INTENT(IN) :: aStringArray(:)
! Body
You're on partially right track. However, it is not string array interface that was changed, but all assumed-shape (and POINTER and ALLOCATABLE) arrays: Intel has one field more in the array descriptor than CVF.
That being said, I don't have an elegant solution. An obvious workaround of changing aStringArray into assumed-size or explicit-shape array doesn't satisfy your "no interface change" condition.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We are facing the following problem:
We want to replace a legacy dll previously compiled with CVF with a new version compiled with Intel Fortran. This dll will be called by both new Intel compiled code as well as from legacy CVF code, which we cannot recompile.
Therefore, we want to make the dll with an external interface that is backward compatible with CVF. This generally works fine by specifying
!DEC$ ATTRIBUTESDLLEXPORT,MIXED_STR_LEN_ARG,REFERENCE,STDCALL,ALIAS : 'abc' :: abc
for the new dll routines.
However, this does not seem to work for arrays of strings. The interface for arrays of string in IVF and CVF seem to be handled different.
Below is a sample code to illustrate the problem.
When both executable and dll are compiled with CVF, things work fine, the output is 'abcdefghi'.
When both are compiled by IVF, also both works fine.
When the executable is compiled by CVF and the dll with Intel, it does not work as expected. The output is abcbcdcde. It also doesn't work when the executable is compiled by IVF and the dll with CVF.
It seems likethere is an offset problem here.It seems like the interface for string arrays was changed between CVF and IVF. Is there any way to ensure backward compatability for string arrays?
Any help on this issue would be greatly appreciated. As said before, we cannot change the interface, as there are existing legacy applications compiled with CVF that we cannot recompile.
Btw, this issue is the same for IVF 11.0.61 or IVF 10.1.025.
best regards,
Thomas Boehme
Sample Code:
!===========================================================
! PassingStringArray_prg.f90
program PassingStringArray_prg
USE PassingStringArray_dll
implicit none
! Variables
CHARACTER(LEN=3), DIMENSION(3) :: strarr
! Body
STRARR(1) = 'abc'
STRARR(2) = 'def'
STRARR(3) = 'ghi'
CALL PassingStringArray(strarr)
end program PassingStringArray_prg
!===========================================
! PassingStringArray_dll.f90
MODULE PassingStringArray_dll
CONTAINS
subroutine PassingStringArray(aStringArray)
!DEC$ ATTRIBUTES DLLEXPORT,MIXED_STR_LEN_ARG,REFERENCE,STDCALL,ALIAS : 'PassingStringArray' :: PassingStringArray
implicit none
! Variables
CHARACTER(LEN=*), INTENT(IN) :: aStringArray(:)
! Body
write(*,*) aStringArray
end subroutine PassingStringArray
END MODULE PassingStringArray_dll
You could usecopymemory
http://msdn.microsoft.com/en-us/library/aa366535(VS.85).aspx
Gerry
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You're on partially right track. However, it is not string array interface that was changed, but all assumed-shape (and POINTER and ALLOCATABLE) arrays: Intel has one field more in the array descriptor than CVF.
That being said, I don't have an elegant solution. An obvious workaround of changing aStringArray into assumed-size or explicit-shape array doesn't satisfy your "no interface change" condition.
A hopefully simpler question: How do I get a scalar assumed-length string trough the interface between IVF EXE and CVF Fortran DLL?
Currently I cannot get them get through regardless of the various combinations of !IDEC I use, except when the subroutine has a single string as argument.
In general I get a string of wrong length which then causes a stack error. Sometimes (if the string is last in the argument list) its length is ok but there is a stack error on exit from sub.
interface
subroutine str(hv,name,stat)
!DEC$ ATTRIBUTES DLLIMPORT, C:: str
! !DEC$ ATTRIBUTES DLLIMPORT, REFERENCE :: str
implicit none
integer,intent(in)::hv
character(*):: name
integer::stat
end subroutine str
endinterface
...
character(20)::name
! Start procedure here
!
name="1234567";hv=1; status=0
call str(hv,name,status)
write(*,*)hv,status,name
...
subroutine str(hv,name,stat)
!DEC$ ATTRIBUTES DLLEXPORT, C :: str ! runs with wrong results
! !DEC$ ATTRIBUTES DLLEXPORT, REFERENCE :: str ! stack overflow or bizarre results
implicit none
integer,intent(in)::hv
character(*):: name
integer::stat
integer::L
L=len(name) ! gives wrong results
write(*,*)"L=",L,name
stat=L+hv
name="ok"
end subroutine str
The problem goes away when string is the only argument.
Steve mentioned about string lengths being passed after all args under IVF and after each individual string in CVF. Though here even switching to string being last doesnt help.
I tried adding MIXED_STR_LEN_ARG or NOMIXED_STR_LEN_ARG but does not seem to help - when used in conjuction with REFERENCE it actually gives the correct L but still stack overflow, whereas with C it just gives wrong results...
Is it some extra IDEC setting I am missing?
---------------------------
Also regarding copymem post just above: Gerry (or anybody else) - Could you please elaborate on this? I am not seeing how could this solve the problem of extra fields in the array descriptor..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Adding MIXED_STR_LEN_ARG on the IVF side (in your interface block) should take care of the problem.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page