- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I'm trying to allocate a Fortran dynamic array in a member function of
a dynamic-linked library written in C.
The compiling and linking is success, but the exacution afterwards has
some problems.
It get stuck at the "new" sentance in the dynamic-linked library member function.
The C++ codes (secso.cpp) for dynamic-linked library:
#include <iostream>
extern "C"
{
int f( double ** array)
{
int j,k;
std::cout << "The allocation 1"<<std::endl;
array[0] = new double [9*3];
std::cout << "The allocation 2"<<std::endl;
for (j=0;j<9;j++)
{
for (k=0;k<3;k++)
{
array[0] [j*3+k] = double((j+1)*10+k+1);
}
}
return 0;
}
}
The Fortran main function code (test.f90):
program test
implicit none
real(kind=8), pointer :: array(:,:)
! External C style function
call f(array)
write (*,*) array
deallocate (array)
end program test
Make file (makefile):
SHELL = /bin/bash
test:
icpc -shared -fPIC -o libsec.so secso.cpp
ifort -assume nounderscore -o test.exe test.f90 -L. -lsec
What should I do?
Any advise would be helpful, thanks in advance.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To some extent, what your code does is similar to two persons writing checks on a single account without either being aware of what the other person is doing. Having Fortran de-allocate memory that was allocated in C, or vice versa, is sure to cause trouble. The following modification of your code works on Windows 32-bit (but it is a quick-and-dirty fix-up, which you should sanitize and adapt for Linux symbol naming conventions, and consistently use only ISO-C-Interoperability methods or only "legacy" methods):
File csub.cpp:
#include <iostream> extern "C" { int F( double ** array) { int j,k; std::cout << "The allocation 1"<<std::endl; array[0] = new double [9*3]; std::cout << "The allocation 2"<<std::endl; for (j=0;j<9;j++) { for (k=0;k<3;k++) { array[0] [j*3+k] = double((j+1)*10+k+1); } } return 0; } } extern "C"{ void C_FREE(void **p){ free(*p); } }
File fmain.f90:
program test use, intrinsic :: iso_c_binding implicit none real(kind=8), pointer :: array(:,:) type(C_PTR) :: cptr_to_array ! External C style function call f(cptr_to_array) call C_F_POINTER (cptr_to_array, array, [3,9]) write (*,*) array call c_free (cptr_to_array) end program test
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would recommend using the extended C interoperability features from draft Fortran 2015, supported in the 16.0 compiler. I'll work up a version of your code done this way.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This isn't your program, but it illustrates how to pass deferred-shape and allocatable arrays from Fortran to C and to have the C code do the allocation.
#include "ISO_Fortran_binding.h" extern int c_alloc (CFI_cdesc_t * descr) { int ret, i; float * array; CFI_index_t lower = 0, upper = 10; ret = CFI_allocate (descr, &lower, &upper, 0); // No elem_len if (ret == CFI_SUCCESS) { array = descr->base_addr; for (i=lower;i<=upper;i++) { array = (float) i; } } return ret; }
use, intrinsic :: iso_c_binding interface function c_alloc (array) bind(C) import integer(C_INT) :: c_alloc real(C_FLOAT), intent(out), allocatable, dimension(:) :: array end function c_alloc end interface real(C_FLOAT), allocatable, dimension(:) :: my_array if (c_alloc(my_array) == 0) then print *, lbound(my_array), ubound(my_array); print *, my_array end if end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank Mr. Lionel and Mr(s) mecej4 for your time and kind reply.
The codes really help me a lot.
My fortran codes now could processing arrays from C style shared library.
Is there any tutorials about shared libraries for beginners like me?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The Intel Fortran documentation has topics on shared libraries. https://software.intel.com/en-us/node/579667 is a current (16.0) documentation link - if that link doesn't work in the future, look under Compiler Reference > Libraries > Creating Shared Libraries.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thank you mr. Steve for reply
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page