- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
Hi. What's the easiest way to pass a 2-d vector from VC++ to VF? I'm aware of the difference in row-column order in VC++ and VF. I also know of passing 1-d vectors from VC++ to VF and was able to do this successfully.
I tried passing a 2-d vector of floats from VC++ to a 2-d array of real*4 in VF but VF didn't retrieve the 2-d array successfully. It was only able to retrieve one element in the 2-d vector. I think it was at (0,2) in VC++ or (1,3) in VF.
Any suggestions?
Thanks,
Angel
I tried passing a 2-d vector of floats from VC++ to a 2-d array of real*4 in VF but VF didn't retrieve the 2-d array successfully. It was only able to retrieve one element in the 2-d vector. I think it was at (0,2) in VC++ or (1,3) in VF.
Any suggestions?
Thanks,
Angel
- Etiquetas:
- Intel® Fortran Compiler
Enlace copiado
4 Respuestas
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
Since you are specifying equivalent floating point data types in VC++ and CVF I don't think you have to explicitly do anything special to pass a matrix of values except to exchange the row and column sizes.
This is a simple example. Suppose your 2-d array in VC++ is a 2x3 size:
I think I have that straight.
You would have problems if VC++ and CVF are arranging the bits of the floating point values differently. In the example above I'm assuming that the representations are the same.
Mike
This is a simple example. Suppose your 2-d array in VC++ is a 2x3 size:
r1c1 r1c2 r1c3 r2c1 r2c2 r2c3VC++ is storing them in memory as:
r1c1 r1c2 r1c3 r2c1 r2c2 r2c3After you pass it to Fortran you should be able to access the values as a transposed 3x2 array with the elements:
r1c1 r2c1 r1c2 r2c2 r1c3 r2c3Continuing with this same example, you could work with the array in Fortran as a 2x3 if you transpose it in VC++ before passing it to Fortran.
I think I have that straight.
You would have problems if VC++ and CVF are arranging the bits of the floating point values differently. In the example above I'm assuming that the representations are the same.
Mike
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
Hi Mike,
here's the code.
-----------------------------------------------------
//C++ code
//Fortran Programs Called By C++
extern "C" {
//function to process meter values
void __stdcall MILLIGAL(int& row, int& col, const double* vCalFile,
int& readingvsize, double* readingvec,
int& metervsize, int* metervec,
char* FNSUM, int num_chars);
}
//Function to pass FLD Data to F90 subroutines for processing
void FldGrav::PassFldGrav(char FNFLD[20], char FNSUM[20], int mark, int nfix,
const std::vector <:VECTOR> >& vCalFile) {
ifstream fldfile(FNFLD, ios::in);
assert(fldfile);
fldfile.seekg(mark);
std::string line;
getline(fldfile, line);
while (getline(fldfile, line)) {
if (!line.empty()) {
stringstream ss(line);
ss>>reading; readingvec.push_back(reading);
ss>>meter; metervec.push_back(meter);
if (ss.fail()) {
meter = 1;
metervec.pop_back();
metervec.push_back(meter);
}
}
}
fldfile.close();
int readingvsize = readingvec.size();
int metervsize = metervec.size();
int row = vCalFile.size();
int col = nmtr_const;
int num_chars = strlen(FNSUM);
//display vectors for testing purposes only
printf("size of vCalFile: %d", row);
for (int i=0; i printf("
");
for (int j=0; j printf("%f ", vCalFile);
}
MILLIGAL (row, col, &vCalFile[0][0],
readingvsize, &readingvec[0],
metervsize, &metervec[0],
FNSUM, num_chars);
readingvec.clear();
metervec.clear();
D.vCalFile.clear();
}
!F90 Code
subroutine Milligal (col, row, calfilevec, readingvsize, mtrrdg, metervsize, imeter, FNSUM)
implicit none
interface
subroutine ForReading(readingvsize,mtrrdg, FNSUM)
!MS$ATTRIBUTES C,REFERENCE, ALIAS:'_ForReading' :: ForReading
integer readingvsize
real*8 mtrrdg(readingvsize)
character*24 FNSUM
end subroutine ForReading
end interface
character*24 FNSUM
integer calmtrvsize, readingvsize, metervsize
integer i, j, col, row, textlen
integer imeter(metervsize)
real*8 calfilevec(row, col), mtrrdg(readingvsize)
write(*,*) row, col
write(*,*)
write(*,*) calfilevec(1,1)
write(*,*) calfilevec(2,1)
write(*,*) calfilevec(3,1)
write(*,*) calfilevec(1,2)
write(*,*) calfilevec(2,2)
write(*,*) calfilevec(3,2)
write(*,*)
write(*,*)
do i = 1,row
do j = 1, col
write(*,*) i, j, calfilevec(i,j)
end do
end do
textlen = len(FNSUM)
FNSUM(textlen:textlen) = char(0)
call ForReading(readingvsize, mtrrdg, FNSUM)
return
end subroutine Milligal
---------------------------------------------------
That's the C++ and Fortran code I wrote for transferring 2D vectors from C++ to Fortran. And it's not working, Fortran only retrieves the 1st row of the 2D vector from C++, but not the 2nd row.
I'm, stuck in this problem for 2 days now. It's getting more and more frustrating. I really hope you can help me out. I wrote another code that does the same thing except that I used arrays instead of vectors but I get the same problem. I really wanted to use vectors instead of arrays, I just tried out using arrays in this case, but to no avail.
Thanks,
Angel
here's the code.
-----------------------------------------------------
//C++ code
//Fortran Programs Called By C++
extern "C" {
//function to process meter values
void __stdcall MILLIGAL(int& row, int& col, const double* vCalFile,
int& readingvsize, double* readingvec,
int& metervsize, int* metervec,
char* FNSUM, int num_chars);
}
//Function to pass FLD Data to F90 subroutines for processing
void FldGrav::PassFldGrav(char FNFLD[20], char FNSUM[20], int mark, int nfix,
const std::vector <:VECTOR>
ifstream fldfile(FNFLD, ios::in);
assert(fldfile);
fldfile.seekg(mark);
std::string line;
getline(fldfile, line);
while (getline(fldfile, line)) {
if (!line.empty()) {
stringstream ss(line);
ss>>reading; readingvec.push_back(reading);
ss>>meter; metervec.push_back(meter);
if (ss.fail()) {
meter = 1;
metervec.pop_back();
metervec.push_back(meter);
}
}
}
fldfile.close();
int readingvsize = readingvec.size();
int metervsize = metervec.size();
int row = vCalFile.size();
int col = nmtr_const;
int num_chars = strlen(FNSUM);
//display vectors for testing purposes only
printf("size of vCalFile: %d", row);
for (int i=0; i
for (int j=0; j printf("%f ", vCalFile
}
MILLIGAL (row, col, &vCalFile[0][0],
readingvsize, &readingvec[0],
metervsize, &metervec[0],
FNSUM, num_chars);
readingvec.clear();
metervec.clear();
D.vCalFile.clear();
}
!F90 Code
subroutine Milligal (col, row, calfilevec, readingvsize, mtrrdg, metervsize, imeter, FNSUM)
implicit none
interface
subroutine ForReading(readingvsize,mtrrdg, FNSUM)
!MS$ATTRIBUTES C,REFERENCE, ALIAS:'_ForReading' :: ForReading
integer readingvsize
real*8 mtrrdg(readingvsize)
character*24 FNSUM
end subroutine ForReading
end interface
character*24 FNSUM
integer calmtrvsize, readingvsize, metervsize
integer i, j, col, row, textlen
integer imeter(metervsize)
real*8 calfilevec(row, col), mtrrdg(readingvsize)
write(*,*) row, col
write(*,*)
write(*,*) calfilevec(1,1)
write(*,*) calfilevec(2,1)
write(*,*) calfilevec(3,1)
write(*,*) calfilevec(1,2)
write(*,*) calfilevec(2,2)
write(*,*) calfilevec(3,2)
write(*,*)
write(*,*)
do i = 1,row
do j = 1, col
write(*,*) i, j, calfilevec(i,j)
end do
end do
textlen = len(FNSUM)
FNSUM(textlen:textlen) = char(0)
call ForReading(readingvsize, mtrrdg, FNSUM)
return
end subroutine Milligal
---------------------------------------------------
That's the C++ and Fortran code I wrote for transferring 2D vectors from C++ to Fortran. And it's not working, Fortran only retrieves the 1st row of the 2D vector from C++, but not the 2nd row.
I'm, stuck in this problem for 2 days now. It's getting more and more frustrating. I really hope you can help me out. I wrote another code that does the same thing except that I used arrays instead of vectors but I get the same problem. I really wanted to use vectors instead of arrays, I just tried out using arrays in this case, but to no avail.
Thanks,
Angel
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
Here is a sample of VC++ calling F95 (the compiler I used was from Lahey, but you should be able to change the pragma for Intel fortran.) I have not tried using vector from the standard library, but I think it should be similar.
! fortran 95 suboutine to be call by MSVC
subroutine sub1(dummy1,dummy2,array1,array2,m,n,fname)
DLL_EXPORT sub1
INTEGER,INTENT(IN) :: m,n
REAL(KIND=8) :: dummy1,dummy2
REAL(KIND=4),DIMENSION(m) :: array1
REAL(KIND=4),DIMENSION(m,n) :: array2
CHARACTER(LEN=80) :: fname
REAL(KIND=16) quad1,quad2
INTEGER :: i,j
quad1 = dummy1**20
quad2 = dummy2**20
PRINT *, "dummy1 = ",dummy1,", dummy2 = ",dummy2
PRINT *, dummy1**20,dummy2**20
dummy1 = dummy1**20; dummy2 = dummy2**20
PRINT *, dummy1,dummy2
PRINT *, "quad1 = ",quad1,", quad2 = ",quad2
PRINT '(8f10.4)',array1
PRINT *,"printing array 2"
PRINT '(f10.4)',((array2(i,j),i=1,m),j=1,n)
!PRINT *, array2
PRINT *, "Fortran 95 array2(3,4) = ", array2(3,4)
PRINT *, "Fortran 95 array2(6,2) = ", array2(6,2)
PRINT *, fname,LEN(fname)
fname = fname // " back from fortran 95"
end
#include
#include
// extern "C" void _stdcall sub1(double*,double*,float[],float[][5]);
extern "C" void _stdcall sub1(double *,double*, float*,float[10][5]);
using namespace std;
void main(void)
{
double ftemp1,ftemp2;
float array1[10];
float array2[10][5];
ftemp1 = 23.4;
ftemp2 = 45.2;
for(int i=0;i<10;i++)
array1 = float(i);
for(int i=0;i<10;i++)
for(int j=0;j<5;j++)
array2 = float(i+j);
sub1(&ftemp1,&ftemp2,array1,array2);
cout << endl;
cout << "ftemp1 =" << ftemp1 << endl;
cout << "ftemp2 =" << ftemp2 << endl;
cout << "done!" << endl;
}
Good Luck!
Long
! fortran 95 suboutine to be call by MSVC
subroutine sub1(dummy1,dummy2,array1,array2,m,n,fname)
DLL_EXPORT sub1
INTEGER,INTENT(IN) :: m,n
REAL(KIND=8) :: dummy1,dummy2
REAL(KIND=4),DIMENSION(m) :: array1
REAL(KIND=4),DIMENSION(m,n) :: array2
CHARACTER(LEN=80) :: fname
REAL(KIND=16) quad1,quad2
INTEGER :: i,j
quad1 = dummy1**20
quad2 = dummy2**20
PRINT *, "dummy1 = ",dummy1,", dummy2 = ",dummy2
PRINT *, dummy1**20,dummy2**20
dummy1 = dummy1**20; dummy2 = dummy2**20
PRINT *, dummy1,dummy2
PRINT *, "quad1 = ",quad1,", quad2 = ",quad2
PRINT '(8f10.4)',array1
PRINT *,"printing array 2"
PRINT '(
!PRINT *, array2
PRINT *, "Fortran 95 array2(3,4) = ", array2(3,4)
PRINT *, "Fortran 95 array2(6,2) = ", array2(6,2)
PRINT *, fname,LEN(fname)
fname = fname // " back from fortran 95"
end
#include
#include
// extern "C" void _stdcall sub1(double*,double*,float[],float[][5]);
extern "C" void _stdcall sub1(double *,double*, float*,float[10][5]);
using namespace std;
void main(void)
{
double ftemp1,ftemp2;
float array1[10];
float array2[10][5];
ftemp1 = 23.4;
ftemp2 = 45.2;
for(int i=0;i<10;i++)
array1 = float(i);
for(int i=0;i<10;i++)
for(int j=0;j<5;j++)
array2
sub1(&ftemp1,&ftemp2,array1,array2);
cout << endl;
cout << "ftemp1 =" << ftemp1 << endl;
cout << "ftemp2 =" << ftemp2 << endl;
cout << "done!" << endl;
}
Good Luck!
Long
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
Angel, could you reduce the sample to a small compilable workspace and attach it (zipped) (C file with a main(), and input file). It's hard to find out what's going on without debugger, and I'm not competent enough with STL to boil it down myself.
Jugosllav
Jugosllav

Responder
Opciones de temas
- Suscribirse a un feed RSS
- Marcar tema como nuevo
- Marcar tema como leído
- Flotar este Tema para el usuario actual
- Favorito
- Suscribir
- Página de impresión sencilla