- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Hi,
I am calling a c function from a fortran program.
the fortran program passes a c type integer pointer to the c function.
the c function dynamically allocates the memory using the malloc funtion,
however on the return to the main fortran program the memory allocated by the c program in NOT retained.
the following is the c function code followed by the fortran program
....
////////// C function (test.c) ///////////
#include
extern "C" void c_func(int *x)
{
x = (int *) malloc(100*sizeof(int));
}
CCCCCC Fortran calling Program (f_callc.f)CCCCCC
PROGRAM FORT_CALLS_C
IMPLICIT NONE
INTERFACE
SUBROUTINE c_func(xval) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING
TYPE(C_PRT), VALUE :: xval
END SUBROUTINE c_func
END INTERFACE
INTEGER(C_INT), ALLOCATABLE :: X(:)
CALL c_func(C_LOC(X))
DEALLOCATE(X)
STOP
END
is there any solution for this particular problem.
Regards,
Gourish
I am calling a c function from a fortran program.
the fortran program passes a c type integer pointer to the c function.
the c function dynamically allocates the memory using the malloc funtion,
however on the return to the main fortran program the memory allocated by the c program in NOT retained.
the following is the c function code followed by the fortran program
....
////////// C function (test.c) ///////////
#include
extern "C" void c_func(int *x)
{
x = (int *) malloc(100*sizeof(int));
}
CCCCCC Fortran calling Program (f_callc.f)CCCCCC
PROGRAM FORT_CALLS_C
IMPLICIT NONE
INTERFACE
SUBROUTINE c_func(xval) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING
TYPE(C_PRT), VALUE :: xval
END SUBROUTINE c_func
END INTERFACE
INTEGER(C_INT), ALLOCATABLE :: X(:)
CALL c_func(C_LOC(X))
DEALLOCATE(X)
STOP
END
is there any solution for this particular problem.
Regards,
Gourish
1 解決策
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Your C function is incorrect. Use
extern "C" void c_func(int **x)
{
*x = (int *) malloc(100*sizeof(int));
}
or better
extern "C" void c_func(int **x, int s)
{
*x = (int *) malloc(s*sizeof(int));
}
**** ALSO ****
Your FORTRAN code is incorrect
The return value is an integer not a FORTRAN array. Your FORTRAN code must convert the integer value into an array descriptor. Also, do not deallocate in FORTRAN what you allocated in C/C++.
PROGRAM FORT_CALLS_C
IMPLICIT NONE
INTERFACE
SUBROUTINE c_func(xval, s) BIND(C) ! ****
USE, INTRINSIC :: ISO_C_BINDING
TYPE(C_PRT), REFERENCE :: xval ! ****
TYPE(C_INT), VALUE :: s! ****
END SUBROUTINE c_func
END INTERFACE
INTEGER(C_INT), ALLOCATABLE :: X(:)
INTEGER(C_PTR) :: pX ! ****
CALL c_func(pX,100)
CALL C_F_POINTER(pX,X, [100])
! *** not here DEALLOCATE(X)
CALL c_func_deallocate(pX,100)
STOP
END
Jim Dempsey
extern "C" void c_func(int **x)
{
*x = (int *) malloc(100*sizeof(int));
}
or better
extern "C" void c_func(int **x, int s)
{
*x = (int *) malloc(s*sizeof(int));
}
**** ALSO ****
Your FORTRAN code is incorrect
The return value is an integer not a FORTRAN array. Your FORTRAN code must convert the integer value into an array descriptor. Also, do not deallocate in FORTRAN what you allocated in C/C++.
PROGRAM FORT_CALLS_C
IMPLICIT NONE
INTERFACE
SUBROUTINE c_func(xval, s) BIND(C) ! ****
USE, INTRINSIC :: ISO_C_BINDING
TYPE(C_PRT), REFERENCE :: xval ! ****
TYPE(C_INT), VALUE :: s! ****
END SUBROUTINE c_func
END INTERFACE
INTEGER(C_INT), ALLOCATABLE :: X(:)
INTEGER(C_PTR) :: pX ! ****
CALL c_func(pX,100)
CALL C_F_POINTER(pX,X, [100])
! *** not here DEALLOCATE(X)
CALL c_func_deallocate(pX,100)
STOP
END
Jim Dempsey
コピーされたリンク
10 返答(返信)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Your C function is incorrect. Use
extern "C" void c_func(int **x)
{
*x = (int *) malloc(100*sizeof(int));
}
or better
extern "C" void c_func(int **x, int s)
{
*x = (int *) malloc(s*sizeof(int));
}
**** ALSO ****
Your FORTRAN code is incorrect
The return value is an integer not a FORTRAN array. Your FORTRAN code must convert the integer value into an array descriptor. Also, do not deallocate in FORTRAN what you allocated in C/C++.
PROGRAM FORT_CALLS_C
IMPLICIT NONE
INTERFACE
SUBROUTINE c_func(xval, s) BIND(C) ! ****
USE, INTRINSIC :: ISO_C_BINDING
TYPE(C_PRT), REFERENCE :: xval ! ****
TYPE(C_INT), VALUE :: s! ****
END SUBROUTINE c_func
END INTERFACE
INTEGER(C_INT), ALLOCATABLE :: X(:)
INTEGER(C_PTR) :: pX ! ****
CALL c_func(pX,100)
CALL C_F_POINTER(pX,X, [100])
! *** not here DEALLOCATE(X)
CALL c_func_deallocate(pX,100)
STOP
END
Jim Dempsey
extern "C" void c_func(int **x)
{
*x = (int *) malloc(100*sizeof(int));
}
or better
extern "C" void c_func(int **x, int s)
{
*x = (int *) malloc(s*sizeof(int));
}
**** ALSO ****
Your FORTRAN code is incorrect
The return value is an integer not a FORTRAN array. Your FORTRAN code must convert the integer value into an array descriptor. Also, do not deallocate in FORTRAN what you allocated in C/C++.
PROGRAM FORT_CALLS_C
IMPLICIT NONE
INTERFACE
SUBROUTINE c_func(xval, s) BIND(C) ! ****
USE, INTRINSIC :: ISO_C_BINDING
TYPE(C_PRT), REFERENCE :: xval ! ****
TYPE(C_INT), VALUE :: s! ****
END SUBROUTINE c_func
END INTERFACE
INTEGER(C_INT), ALLOCATABLE :: X(:)
INTEGER(C_PTR) :: pX ! ****
CALL c_func(pX,100)
CALL C_F_POINTER(pX,X, [100])
! *** not here DEALLOCATE(X)
CALL c_func_deallocate(pX,100)
STOP
END
Jim Dempsey
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Note, the func_deallocate(pX,100) might not require the size..
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
There is a Fortran elemental intrinsic function MALLOC, which you could use instead perhaps?
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Anthony,
The OP's post was (likely) sketch code. The real app will likely do something other than simply allocate memory else why not simply use ALLOCATE. There is one exception to this and that is when using a scalable allocator whereby allocations/deallocations do not pass through a unified heap but instead are obtained via a thread distributed database of similar (chunk) sized allocations. The C/C++ code for thisis typically easirer to implement and/or you have ready made libraries/functions to do this.
Jim Dempsey
The OP's post was (likely) sketch code. The real app will likely do something other than simply allocate memory else why not simply use ALLOCATE. There is one exception to this and that is when using a scalable allocator whereby allocations/deallocations do not pass through a unified heap but instead are obtained via a thread distributed database of similar (chunk) sized allocations. The C/C++ code for thisis typically easirer to implement and/or you have ready made libraries/functions to do this.
Jim Dempsey
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
yes, it is a sketch code, and I am passing the dynamic variable from the fortran code to an already existing C code which does some bit of processing on a predefined dataset and returns the result in the fortran array.
I was easier to use the existing libraries in C than making the libraries in Fotran from scratch, also there is an added advantage of maintaing libraries in C, so they can be used for some other C programs as well.
Thanks,
Gourish
I was easier to use the existing libraries in C than making the libraries in Fotran from scratch, also there is an added advantage of maintaing libraries in C, so they can be used for some other C programs as well.
Thanks,
Gourish
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
the instrunction
TYPE(C_PRT), REFERENCE :: xval ! ****
gives an compiling error which states as
error #6659 : Not an attribute-spec keyword[REFERENCE]
I am using Intel visual fortran 11.1.065 compiler, on visual studio 2008,
is this a feature which is not supported on the above mentioned compiler ?
Gourish
TYPE(C_PRT), REFERENCE :: xval ! ****
gives an compiling error which states as
error #6659 : Not an attribute-spec keyword[REFERENCE]
I am using Intel visual fortran 11.1.065 compiler, on visual studio 2008,
is this a feature which is not supported on the above mentioned compiler ?
Gourish
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
There is no such attribute in the language. REFERENCE is, effectively, the default. There is a VALUE attribute that is supported.
If you are using !DEC$ ATTRIBUTES C (I didn't look), which changes the default to VALUE, you would need to use:
!DEC$ ATTRIBUTES REFERENCE :: xval after the declaration as TYPE(C_PTR) (I hope that's what you meant and not C_PRT).
If you use the F2003 C interoperability features, with BIND(C), then reference is the default.
If you are using !DEC$ ATTRIBUTES C (I didn't look), which changes the default to VALUE, you would need to use:
!DEC$ ATTRIBUTES REFERENCE :: xval after the declaration as TYPE(C_PTR) (I hope that's what you meant and not C_PRT).
If you use the F2003 C interoperability features, with BIND(C), then reference is the default.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I changed the fortran program by using !DEC$ ATTRIBUTES REFERENCE :: xval statement, and it worked
perfectly
!!!!!!!!!! Corrected Sample Code !!!!!!!!!!
PROGRAM FORT_CALLS_C
IMPLICIT NONE
INTERFACE
SUBROUTINE c_func(xval, s) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING
TYPE(C_PTR) :: xval ! ****
!DEC$ ATTRIBUTES REFERENCE :: xval ! ****
TYPE(C_INT), VALUE :: s
END SUBROUTINE c_func
END INTERFACE
INTEGER(C_INT), ALLOCATABLE :: X(:)
TYPE(C_PTR) :: pX ! ****
CALL c_func(pX,100)
CALL C_F_POINTER(pX, X, [100])
CALL c_func_deallocate(pX,100)
STOP
END
perfectly
!!!!!!!!!! Corrected Sample Code !!!!!!!!!!
PROGRAM FORT_CALLS_C
IMPLICIT NONE
INTERFACE
SUBROUTINE c_func(xval, s) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING
TYPE(C_PTR) :: xval ! ****
!DEC$ ATTRIBUTES REFERENCE :: xval ! ****
TYPE(C_INT), VALUE :: s
END SUBROUTINE c_func
END INTERFACE
INTEGER(C_INT), ALLOCATABLE :: X(:)
TYPE(C_PTR) :: pX ! ****
CALL c_func(pX,100)
CALL C_F_POINTER(pX, X, [100])
CALL c_func_deallocate(pX,100)
STOP
END
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I find that a bit odd - ATTRIBUTES REFERENCE should have no effect there. I notice your C code uses "int" for malloc - this won't work on 64-bit systems.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Sorry about the reference thing. (and C_PRT vs C_PTR)
The type of object (array) pointed to is immaterial. cast to (int*) or (char*) for the malloc'd memory would make no difference (except for matching the pointer type in the function signature).
Jim
The type of object (array) pointed to is immaterial. cast to (int*) or (char*) for the malloc'd memory would make no difference (except for matching the pointer type in the function signature).
Jim