- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am working on OPS-DSL, which is DSL framework for auto-generation of parallel codes for structured grid applications.
In Fortran side we have subroutine which are used to pass address of an integer scalar variable which will be stored in char pointer in C side.
This is the C bind function
https://github.com/OP-DSL/OPS/blob/bf90f065fc7f1271a9aa0c1528c9d3dc0dcb8c28/ops/fortran/src/ops_for_declarations.F90#L374C8-L383C35
function ops_arg_gbl_c ( data, dim, size, acc ) BIND(C,name='ops_arg_gbl_char')
use, intrinsic :: ISO_C_BINDING
import :: ops_arg
type(ops_arg) :: ops_arg_gbl_c
type(c_ptr), value :: data
integer(kind=c_int), value :: dim, size
integer(kind=c_int), value :: acc
end function ops_arg_gbl_c
and related C function is
https://github.com/OP-DSL/OPS/blob/bf90f065fc7f1271a9aa0c1528c9d3dc0dcb8c28/ops/c/src/core/ops_lib_core.cpp#L1074
ops_arg ops_arg_gbl_char(char *data, int dim, int size, ops_access acc) {
return ops_arg_gbl_core(data, dim, size, acc);
}
and we have interface for transferring integer scalars or arrays from Fortran
interface ops_arg_gbl
module procedure ops_arg_gbl_int_scalar, ops_arg_gbl_int_1dim,
end interface ops_arg_gbl
type(ops_arg) function ops_arg_gbl_int_scalar(data, dim, typ, access)
use, intrinsic :: ISO_C_BINDING
implicit none
integer(4), target :: data
integer(kind=c_int) :: dim
character(kind=c_char,len=*) :: typ
integer(kind=c_int) :: access
! warning: access is in FORTRAN style, while the C style is required here
ops_arg_gbl_int_scalar = ops_arg_gbl_c( c_loc(data) , dim, 4, access-1 )
end function ops_arg_gbl_int_scalar
type(ops_arg) function ops_arg_gbl_int_1dim(data, dim, typ, access)
use, intrinsic :: ISO_C_BINDING
implicit none
integer(4), dimension(*), target :: data
integer(kind=c_int) :: dim
character(kind=c_char,len=*) :: typ
integer(kind=c_int) :: access
! warning: access is in FORTRAN style, while the C style is required here
ops_arg_gbl_int_1dim = ops_arg_gbl_c( c_loc(data) , dim, 4, access-1 )
end function ops_arg_gbl_int_1dim
so when we call something like this
ops_arg_gbl(dummy_int_arr, 4, "integer(kind=4)", OPS_READ)
where we want to transfer integer array from fortran of size 4 elements, and then rertieve the content of it later by converting char_ptr to correct integer pointer, we get correct values.
but when trying scalar varaible, it doesnt work. We get wrong values when we try convert the char_ptr back to Fortran integer pointer and retrieve the content pointed by the address in char_ptr
ops_arg_gbl(int_var, 1, "integer(kind=4)", OPS_READ)
any idea what is wrong here.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What is type(ops_arg)?
I am not sure what happens if "type ops_arg" is not equivalent to (same sizeof as) a scalar (character, integer(1,2,4,8), real(4,8))
Maybe Steve L can comment on this.
What I suggest you do replace the function with a subroutine, and pass in the address of (reference to) the type(ops_arg).
See what happens
FWIW, I have written some interfaces to C code that interfaces with the HDF5 library
INTERFACE
...(cut) ...
function HDF5_Read_Attribute_Integer(Place_c, Name_c, Value) bind(C,NAME='HDF5_Read_Attribute_Integer') result(ret)
USE, INTRINSIC :: ISO_C_BINDING
use H5FORTRAN_TYPES
use H5global
implicit none
type(C_PTR), value :: Place_c, Name_c
integer :: Value
integer :: ret
end function HDF5_Read_Attribute_Integer
function HDF5_Write_Attribute_Integer_Array(Place_c, Name_c, Array, rank, dims) bind(C,NAME='HDF5_Write_Attribute_Integer_Array') result(ret)
USE, INTRINSIC :: ISO_C_BINDING
use H5FORTRAN_TYPES
use H5global
implicit none
type(C_PTR), value :: Place_c, Name_c, Array
integer, value :: rank
type(C_PTR), value :: dims
integer :: ret
end function HDF5_Write_Attribute_Integer_Array
...(cut) ...
END INTERFACE
In my case, the return is a scalar (error code)
Those are examples of passing a scalar, and array, into an HDF5 shell function (which in turn calls the HDF5 C++ code).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Jim,
OPS_ARG is a structure in C++ and we have BIND type in Fortran as well.
C side
https://github.com/OP-DSL/OPS/blob/bf90f065fc7f1271a9aa0c1528c9d3dc0dcb8c28/ops/c/include/ops_lib_core.h#L501
Fortran side
https://github.com/OP-DSL/OPS/blob/bf90f065fc7f1271a9aa0c1528c9d3dc0dcb8c28/ops/fortran/src/ops_for_declarations.F90#L125
if i declare another variable with attribute target and then pass it ops_arg_gbl, it works
the original variable has parameter attribute associated with it
integer(kind=4), parameter :: nxglbl=128
ops_arg_gbl(nxglbl, 1, "integer(kind=4)", OPS_READ) ! doesnt work
-------------------------------------------
integer(kind=4), parameter :: nxglbl=128
integer(kind=4), target :: nxglbl_target
nxglbl_target = nxglbl
ops_arg_gbl(nxglbl_target, 1, "integer(kind=4)", OPS_READ) ! works
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
integer(kind=4), parameter :: nxglbl=128
ops_arg_gbl(nxglbl, 1, "integer(kind=4)", OPS_READ) ! doesnt work
**** if ops_arg_gbl is a function
**** the above statement is in error as there is no left hand side=
**** if ops_arg_gbl is a function
**** there is no call keyword
-------------------------------------------
integer(kind=4), parameter :: nxglbl=128
integer(kind=4), target :: nxglbl_target
nxglbl_target = nxglbl
ops_arg_gbl(nxglbl_target, 1, "integer(kind=4)", OPS_READ) ! works
**** if ops_arg_gbl is a function
**** the above statement is in error as there is no left hand side=
**** if ops_arg_gbl is a function
**** there is no call keyword
If your actual code is different, please include a complete code snip.
Assuming missing "call" or "something=" what I see as a significant difference is not only the target, but also one argument is a parameter.
The parameter may be the cause for the "bug"
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The problem you have encountered is very likely an issue *specific* to the circumstances of your program rather than anything general as implied by your title, "Problem in passing Integer scalar variable from Fortran to C"
You can confirm this using a very simple and silly case as shown below:
- C "library" code
#include <stdio.h>
void Cfunc(int n, char *s) {
printf("In Cfunc, n = %d; %s\n", n, s);
}
- Fortran calling program
use, intrinsic :: iso_c_binding, only : c_int, c_char, c_null_char
interface
subroutine Cfunc( n, s ) bind(C, name="Cfunc")
import :: c_int, c_char
integer(c_int), intent(in), value :: n
character(kind=c_char,len=1), intent(in) :: s(*)
end subroutine
end interface
integer(c_int) :: a
character(kind=c_char,len=:), allocatable :: m
a = 42 ; m = c_char_"Hello World!" // c_null_char
call Cfunc( a, m )
end
- Program behavior on Windows OS in a console setting using Intel Fortran compiler
C:\temp>cl /c /W3 /EHsc c.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.36.32537 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
c.c
C:\temp>ifx /c /free /standard-semantics p.f
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.1.0 Build 20240308
Copyright (C) 1985-2024 Intel Corporation. All rights reserved.
C:\temp>link p.obj c.obj /subsystem:console /out:p.exe
Microsoft (R) Incremental Linker Version 14.36.32537.0
Copyright (C) Microsoft Corporation. All rights reserved.
C:\temp>p.exe
In Cfunc, n = 42; Hello World!
C:\temp>
So you should expect the same response in your environment using the above code by following your OS-specific steps and the C companion processor with Intel Fortran compiler, of course.
You can then review this code vis-a-vis your actual code and look for any root-cause(s), as to the problem you face.
Note for any further help from any reader here, you will likely need to provide a minimal working example (MWE).

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page