Silverfrost Forums

Welcome to our forums

Format of FTN95 array descriptor (porting woe #3)

14 Nov 2005 8:15 #436

I'm porting my Xeffort GUI library from Visual Fortran to FTN95 (among other compilers). The code uses a lot of 'smart' non-standard tricks (since VF has pretty much full capabilites of C language) and I'm trying to find out how to find equivalent constructs in FTN95.

In order to achieve as much as portability in 'main' code, I decided to implement my own version of ISO_C_BINDING module in favor of Cray pointers. I had to use some cheats to make it work on 'implementation' side. For example, here's how I build up a pointer to array of TYPE(X_POINT)'s: [pre] !***Low-level implementation (VF-specific) ***

!======================================= SUBROUTINE C_F_POINTERArray(cPtr, fPtr, iDim, iSizeOf)

TYPE VF_DIMENSION SEQUENCE INTEGER iExtent INTEGER iDistance INTEGER iLowerBound END TYPE VF_DIMENSION

TYPE VF_1D_DESCRIPTOR SEQUENCE INTEGER(INT_PTR_KIND()) lpAddress INTEGER nSize INTEGER iOffset INTEGER iAllocated INTEGER iRank #ifdef __INTEL_COMPILER INTEGER iWhatever #endif TYPE(VF_DIMENSION) Dim1 END TYPE VF_1D_DESCRIPTOR

INTEGER, PARAMETER:: VF_EXISTING = Z'03000001' INTEGER, PARAMETER:: VF_SECTPTR = Z'00000002' INTEGER, PARAMETER:: VF_OWNMEMORY = Z'00000004'

INTEGER(INT_PTR_KIND()):: cPtr TYPE(VF_1D_DESCRIPTOR):: fPtr INTEGER, INTENT(IN):: iDim INTEGER, INTENT(IN):: iSizeOf

fPtr%lpAddress = cPtr fPtr%nSize = iSizeOf fPtr%iOffset = -iSizeOf fPtr%iAllocated = VF_EXISTING fPtr%iRank = 1 #ifdef __INTEL_COMPILER fPtr%iWhatever = 0 #endif fPtr%Dim1%iExtent = iDim fPtr%Dim1%iDistance = iSizeOf fPtr%Dim1%iLowerBound = 1

END SUBROUTINE C_F_POINTERArray !================================== !***Interface to the rest of the code ***

MODULE ISO_C_BINDINGS

INTERFACE C_F_POINTER ... MODULE PROCEDURE C_F_POINTER_POINTS ... END INTERFACE

!======================================= SUBROUTINE C_F_POINTER_POINTS(cPtr, fPtr, iShape)

INTEGER(C_POINTER):: cPtr TYPE(X_POINT), POINTER:: fPtr(:) INTEGER, INTENT(IN):: iShape(:)

TYPE(X_POINT):: xPt INTEGER(C_CHAR):: Mold

INTERFACE SUBROUTINE C_F_POINTERArray(cPtr, fPtr, iShape, iSize) USE ISO_C_BINDING_TYPES USE XFTTYPES INTEGER(C_POINTER):: cPtr TYPE(X_POINT), POINTER:: fPtr(:) INTEGER:: iShape INTEGER:: iSize END SUBROUTINE C_F_POINTERArray END INTERFACE

CALL C_F_POINTERArray(cPtr, fPtr, iShape(1), SIZE(TRANSFER(xPt, (/Mold/))) )

END SUBROUTINE C_F_POINTER_POINTS

!=================================== !***Finally, F2003-like call ***

USE ISO_C_BINDING

TYPE(X_POINT), POINTER:: xMinMax(:)

CALL C_F_POINTER(lParam, xMinMax, (/5/)) [/pre] Now, to do the same in FTN95, I need to know the low-level format of FTN95 array-descriptor (namely, format of a pointer-to-array), as well as the calling convention (VF passes a reference to VF_1D_DESCRIPTOR structure, and I'd expect that similar mechanism is used in FTN95). Is this information available?

-- Jugoslav

15 Nov 2005 11:44 #443

Jugoslav

The information you require is not readily available. It would be necessary to research this for you and unfortunately we do not have the resources to do this for free.

17 Nov 2005 1:35 #447

Thanks Paul, I resolved most of the issues myself: *reverse-engineered the descriptor format 🆒

  • changed OPEN(FILE=BINARY) to CreateFile/WriteFile/CloseHandle
  • I found out how to cheat with C_EXTERNAL(VAL) declaration and FUNCTION(EXTERNAL foo) definition
  • Guess I can live with location of .obj and .mod files

I can post code samples if anyone's interested 😃

However, the biggest obstacle (that could stop me from doing this port at all is):

How do I write a WNDPROC in FTN95???

A Win32 WNDPROC has prototype STDCALL WndProc(VAL, VAL, VAL, VAL): INTEGER. But it doesn't seem to be possible to write a native FTN procedure which receives arguments by value???

An ugly resolution I can think of is to write [pre]F_STDCALL FUNCTION MyWndProc(phWnd, pmsg, pwParam, plParam) INTEGER MyWndProc INTEGER phWnd,pmsg,pwParam,plParam

INTEGER hWnd,msg,wParam,lParam hWnd = LOC(phWnd) msg = LOC(pmsg) wParam = LOC(pwParam) lParam = LOC(plParam) [/pre] In effect, I will receive the arguments by reference, and convert them to value using LOC...

To add salt to the insult, F_STDCALL functions cannot be MODULE PROCEDURES... ugh :mad:. And apart from WNDPROCs, I have dozen other functions that need to be F_STDCALL (callbacks to EnumWindows, hooks...).

P.S. E-mail notification doesn't seem to work?

-- Jugoslav

17 Nov 2005 11:22 #450

Jugoslav

The idea of using LOC to pass 32 bit integers by value is a clever one that should work. The only other alternative that I can think of is to write this part in C and compile with SCC. The FTN95 compiler is compiled using SCC and the two compilers are designed to work together.

18 Nov 2005 5:02 #451

OK, I'm trying to keep this project all-fortran so i'll give it a try.

By the way, I managed to crash the compiler (in a simply-reproducible manner). I found a workaround, but should I send the code somewhere (here?).

Note that I'm currently using Personal Edition (and I'm doing this project mostly for the fun of it (sic!) ) and I don't expect a 'real' support. However, if you're interested in fixing this for future releases, I'll submit the test case.

Regards,

-- Jugoslav

Please login to reply.