- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My first attempt at mixed language programming is working but I'm obviously missing some crucial step because weird things happen to the values of some variables after I return to Fortran. For example, I want to get the number of rows and columns in a TIFF image so I call a C routine with the following interface ...
interface
subroutine c_get_tiff_size(fullname,pnrows,pncols,pcOK)
!DEC$ ATTRIBUTES C :: c_get_tiff_size
character(*) fullname
integer*4 nrows,ncols
logical cOK
!DEC$ ATTRIBUTES REFERENCE :: fullname,pnrows,pncols,pcOK
pointer (pnrows,nrows),(pncols,ncols),(pcOK,cOK)
end subroutine c_get_tiff_size
end interface
Outside the interface declaration I have ...
integer*4 ncols,nrows
pointer (pncols,ncols),(pnrows,nrows)
And my call to the c routine is ...
call c_get_tiff_size(fullname,pncols,pnrows,pcOK)
At frst, on return, the values of ncols and nrows are correct, but a few lines further on, after some seemingly irrelevant call, the values become fantastically wrong. It's not the particular call that causes this effect because other calls have the same effect on other variables. I can get around the problem by immediately capturing the values in other local variables, but this is a poor solution. I presume the problem has something to do with the fact that both ncols and nrows are pointees, but I don't know what to do about it. Please can someone explain?
With many thanks in advance,
Mike
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
uint32* &pncols,
uint32* &pnrows,
uint32* &pcOK)
{
TIFF *tif;
uint32 cOK;
//Supress warnings about unknown tags, i.e. georeferences tags, etc
TIFFErrorHandler oldhandler;
oldhandler = TIFFSetWarningHandler(NULL);
//Open tiff file for reading
tif = TIFFOpen(fullname, "r");
if(tif) {
uint32 ncols,nrows;
cOK = 1;
pcOK = &cOK;
//Get image width (number of columns).
if (TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &ncols) == 0)
{
cOK = 0;
return;
}
//Get image height (number of rows).
if (TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &nrows) == 0)
{
cOK = 0;
return;
}
pncols = &ncols;
pnrows = &nrows;
TIFFClose(tif);
}
else
{
cOK = 0;
pcOK = &cOK;
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
You have used pointers (pnrows,pncols, pcOk) that are assigned in the stack of the C function so the addresses become invalid after the return to the caller.
I propose a more simple implementation :
Interface
interface
logical*4 function c_get_tiff_size(fullname,nrows,ncols)
!DEC$ ATTRIBUTES C :: c_get_tiff_size
character(*) fullname
integer*4 nrows,ncols
!DEC$ ATTRIBUTES REFERENCE :: fullname,nrows,ncols
end function c_get_tiff_size
end interface
Variables declaration
integer*4 ncols,nrows
logical*4 cOk
CALL
cOk=c_get_tiff_size(fullname,ncols,nrows)
C function
uint32 *ncols,
uint32 *nrows)
{
TIFF *tif;
//Supress warnings about unknown tags, i.e. georeferences tags, etc
TIFFErrorHandler oldhandler;
oldhandler = TIFFSetWarningHandler(NULL);
//Open tiff file for reading
tif = TIFFOpen(fullname, "r");
if(tif)
{
//Get image width (number of columns).
if (TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, ncols) != 0)
{
//Get image height (number of rows).
if (TIFFGetField(tif, TIFFTAG_IMAGELENGTH, nrows) != 0)
cOk=TRUE;// 1
}
TIFFClose(tif);
}
return(cOk);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
logical*4 function c_get_tiff_header(fullname,emin,nmax,nrows,ncols,de,dn)
!DEC$ ATTRIBUTES C :: c_get_tiff_header
character(*) fullname
integer*4 nrows,ncols
real*8 emin,nmax,de,dn
!DEC$ ATTRIBUTES REFERENCE :: fullname,emin,nmax,nrows,ncols,de,dn
end function c_get_tiff_header
end interface
double *xorig,
double *yorig,
uint32 *ncols,
uint32 *nrows,
double *dx,
double *dy)
{
TIFF *tif;
int OK = FALSE;
//Supress warnings about unknown tags, i.e. georeferences tags, etc
TIFFErrorHandler oldhandler;
oldhandler = TIFFSetWarningHandler(NULL);
//Open tiff file for reading
tif = TIFFOpen(fullname, "r");
if(tif) {
double *origin = 0;
double *cellsize = 0;
uint16 count;
//Get origin (centre dot of upper left pixel). 33922 is "MultiTiePointTag" ("GeoreferenceTag").
if (TIFFGetField(tif, 33922, &count, &origin)!=0)
{
xorig = &origin[3];
yorig = &origin[4];
}
else
{
return(OK);
}
//Get pixel size. 33550 is "ModelPixelScaleTag".
if (TIFFGetField(tif, 33550, &count, &cellsize)!=0)
{
dx = &cellsize[0];
dy = &cellsize[1];
}
else
{
return(OK);
}
//Get image width (number of columns).
if (TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, ncols)== 0)
{
return(OK);
}
//Get image height (number of rows).
if (TIFFGetField(tif, TIFFTAG_IMAGELENGTH, nrows)== 0)
{
return(OK);
}
TIFFClose(tif);
OK = TRUE;
return(OK);
}
}
On return from this function, on the Fortran side, ncols and nrows have the correct values, but emin, nmax, de, and dn all have values of zero. Do you have any further suggestions?
With many thanks
Mike
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are confusing variables and pointers.
in C langage :
int dummy;
dummy is a variable
&dummy is the address of the content of the dummy variable
if you want to change the value of dummy write dummy="something";
int *dummy;
dummy is a pointer
so if you write
dummy="something" you set the pointer value
*dummy="something" you set the value pointed by dummy.
So in you C functions, if you want to return a value proceed as below :
void myfunction(int *dummy) // dummy is a pointer
*dummy="something"; // set the value pointed by dummy
In your code you wrote
dummy=&"something"; // does'nt change the value pointed by dummy but change the pointer value.
I think it is better for you learn more about C pointers in a C test application before using them in mixed langage.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page