Home > Archive > Fortran > January 2006 > Strange problem with pointers
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Strange problem with pointers
|
|
| roko1076 2006-01-27, 7:01 pm |
| Hello everybody,
I=B4m new in this group and also new to Fortran90 - so I=B4m asking you
for help in a case, that might sound a little funny to you...
In my program I=B4m dealing with the import/export of data in a dll. I
wrote a fine interface (putting things like DLLIMPORT, .. in it - and
it even work's nicely) to the dll - because of the ALIAS problem with
dll=B4s written in C... So far so good - but trouble started with the
need of handing over a pointer in a function call to the dll - this
very pointer problem starts getting me crazy...
Let me show you some of the code concerned with the problem:
________________________________________
_________________________
PROGRAM epsilon
USE MSFLIB
REAL eps, oneeps
INTEGER*4, DIMENSION(3:256), TARGET::tCalcData
INTEGER*4, POINTER::pData
..=2E.
! defining an interface to Calc.dll
INTERFACE
INTEGER*2 FUNCTION CalcReadData(iUserCode, pData, iCount)
!MS$ATTRIBUTES DLLIMPORT,STDCALL,ALIAS:
'_Calc_ReadData@20'::CalcReadData
!MS$ATTRIBUTES VALUE::iSegment
!MS$ATTRIBUTES REFERENCE::pData
!MS$ATTRIBUTES VALUE::iCount
INTEGER*4 iUserCode
INTEGER*4, POINTER:: pData
INTEGER*2 iCount
END FUNCTION
END INTERFACE
..=2E.
pData =3D> tCalcData(0)
outData =3D CalcReadData(14, pData, 10)
WRITE(*,*) ' Wert aus der Berechnung: ', tCalcData(1)
WRITE(*,*) ' Wert aus der Berechnung: ', tCalcData(2)
WRITE(*,*) ' Wert aus der Berechnung: ', tCalcData(3)
WRITE(*,*) ' Wert aus der Berechnung: ', tCalcData(4)
WRITE(*,*) ' Wert aus der Berechnung: ', tCalcData(5)
________________________________________
_________________________
The result is now interesting:
***
Calculation.dll geladen!
..=2E.
Wert aus der Berechnung: 1
Wert aus der Berechnung: 2
Wert aus der Berechnung: 3
Wert aus der Berechnung: 4
Wert aus der Berechnung: 0
..=2E.
Calculation.dll entladen!
________________________________________
_____________________________
The values of tCalcData are correct only if the spectrum of tCalcData
is set with the borders of --!!3!!-- to 256 - see code:
INTEGER*4, DIMENSION(3:256), TARGET::tCalcData
if set to (1:256) I get the following results:
Wert aus der Berechnung: 3
Wert aus der Berechnung: 4
Wert aus der Berechnung: 0
Wert aus der Berechnung: 0
Wert aus der Berechnung: 0
The values are for shure set in correct order in the dll 1,2,3,...!
My ultimative question: Why is this behaviour happening? What could be
done to fix this misbehaviour? Is it the pointer
definition/implementation? I very greatful for all help - this problem
is literally burning under my nails...;-))
I hope that I could also add my xperiences to this forum as soon as
I=B4m a little more expirienced with this complex language!
Thanx in advane to all of you and a nice w end,
Richard
| |
| Jugoslav Dujic 2006-01-27, 7:01 pm |
| roko1076 wrote:
| Hello everybody,
|
| I´m new in this group and also new to Fortran90 - so I´m asking you
| for help in a case, that might sound a little funny to you...
|
| In my program I´m dealing with the import/export of data in a dll. I
| wrote a fine interface (putting things like DLLIMPORT, .. in it - and
| it even work's nicely) to the dll - because of the ALIAS problem with
| dll´s written in C... So far so good - but trouble started with the
| need of handing over a pointer in a function call to the dll - this
| very pointer problem starts getting me crazy...
|
| Let me show you some of the code concerned with the problem:
| ________________________________________
_________________________
| PROGRAM epsilon
|
| USE MSFLIB
|
| REAL eps, oneeps
|
| INTEGER*4, DIMENSION(3:256), TARGET::tCalcData
| INTEGER*4, POINTER::pData
| ...
|
| ! defining an interface to Calc.dll
|
| INTERFACE
| INTEGER*2 FUNCTION CalcReadData(iUserCode, pData, iCount)
| !MS$ATTRIBUTES DLLIMPORT,STDCALL,ALIAS:
| '_Calc_ReadData@20'::CalcReadData
| !MS$ATTRIBUTES VALUE::iSegment
| !MS$ATTRIBUTES REFERENCE::pData
| !MS$ATTRIBUTES VALUE::iCount
|
| INTEGER*4 iUserCode
| INTEGER*4, POINTER:: pData
| INTEGER*2 iCount
| END FUNCTION
| END INTERFACE
| ...
|
| pData => tCalcData(0)
|
| outData = CalcReadData(14, pData, 10)
|
| WRITE(*,*) ' Wert aus der Berechnung: ', tCalcData(1)
| WRITE(*,*) ' Wert aus der Berechnung: ', tCalcData(2)
| WRITE(*,*) ' Wert aus der Berechnung: ', tCalcData(3)
| WRITE(*,*) ' Wert aus der Berechnung: ', tCalcData(4)
| WRITE(*,*) ' Wert aus der Berechnung: ', tCalcData(5)
| ________________________________________
_________________________
| The result is now interesting:
|
| ***
| Calculation.dll geladen!
| ...
| Wert aus der Berechnung: 1
| Wert aus der Berechnung: 2
| Wert aus der Berechnung: 3
| Wert aus der Berechnung: 4
| Wert aus der Berechnung: 0
| ...
| Calculation.dll entladen!
| ________________________________________
_____________________________
| The values of tCalcData are correct only if the spectrum of tCalcData
| is set with the borders of --!!3!!-- to 256 - see code:
|
| INTEGER*4, DIMENSION(3:256), TARGET::tCalcData
|
| if set to (1:256) I get the following results:
|
| Wert aus der Berechnung: 3
| Wert aus der Berechnung: 4
| Wert aus der Berechnung: 0
| Wert aus der Berechnung: 0
| Wert aus der Berechnung: 0
|
| The values are for shure set in correct order in the dll 1,2,3,...!
|
| My ultimative question: Why is this behaviour happening? What could be
| done to fix this misbehaviour? Is it the pointer
| definition/implementation? I very greatful for all help - this problem
| is literally burning under my nails...;-))
If it is, Friday at 5PM was not the biggest time to post the question ;-).
People tend to rush home at these hours and forget about Fortran & everything.
You didn't show us the C prototype of the dll function; if it's an int*,
(pointer to an array of integers), you can simply omit the pointer attribute
from the interface (and pass the tCalcData directly instead of pData, but
that doesn't make a difference). In C, presence of * in argument-list simply
means
that the call is by reference, and Fortran does the call by reference* anyway.
POINTER attribute adds one more level of indirection, so with the current
version you have a serious overwrite of contents of neighbouring variables.
If it's an int**, (pointer to pointer of an array of integers), you have a
problem.... but I gotta run now, so I probably won't be able to reply by
Monday.
*) disclaimer: Fortran does not always do call by reference, but many compilers
will in most situations, and Visual Fortran certainly in this case.
--
Jugoslav
___________
www.xeffort.com
Please reply to the newsgroup.
You can find my real e-mail on my home page above.
|
|
|
|
|