- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Hi,
Is there a way to move the data from a pointer to an allocatable without doing a copy ?
The data is allocated in C, but used and deallocated in fortran in a dimension(:),pointer, but then it needs to be attached to a class, but i dont see a way of moving the data to the allocatable without a copy.
Thanks.
Pat.
링크가 복사됨
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
No, you can't do this. And I hope you aren't using Fortran DEALLOCATE to deallocate storage allocated in C. You can convert a C pointer to a Fortran pointer (which you aren't allowed to deallocate), but ALLOCATABLEs are in their own realm. Polymorphism is another barrier here - even with the new C descriptor support in 16.0, you can't make polymorphic objects interoperable with C.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Just to have clear idea on what i am talking about here is a sample code below. I understand for a structure it is complicated but for a basic type , as long as i keep track of all my allocation and I am sure this pointer is not referenced anywhere else i should be ok ?
#include <stdlib.h>
#include <stdio.h>
int* alloc(int n)
{
int i;
int *p=malloc(sizeof(int)*n);
printf("allocate int array size %d\n",n);
for (i=0;i<n;i++){
p=i;
printf("p %d = %d\n",i,p);
}
return p;
}
and
program foo use iso_c_binding type(c_ptr) :: c_array integer ,dimension(:),pointer ::fc_array integer ,dimension(:),allocatable :: array integer :: n interface type(c_ptr) function alloc(n) bind(c) use iso_c_binding integer(c_int),value :: n end function end interface n=20 c_array=alloc(n) call c_f_pointer(c_array,fc_array,(/n/)) print *,fc_array !move fc_array storage to fc_array ?? allocate(array(n)) array=fc_array deallocate(array) ! Forbidden ???? but working ? deallocate(fc_array) end program foo
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
That last deallocate is indeed forbidden. That it seems to "work" is an accident, and it could corrupt memory. Don't do it. But you can now (in 16.0) do this:
#include "ISO_Fortran_binding.h"
#include <stdio.h>
#include <stdlib.h>
extern "C" int alloc(CFI_cdesc_t * dv, int n) {
CFI_index_t lower[1], upper[1];
int i, ret;
int* p;
lower[0] = 1;
upper[0] = n;
ret = CFI_allocate(dv, lower, upper, 0);
if (ret == CFI_SUCCESS) {
printf("allocate int array size %d\n", n);
p = (int *) dv->base_addr;
for (i = 0; i < n; i++){
p = i;
printf("p %d = %d\n", i, p);
}
}
return ret;
}
program foo use iso_c_binding integer(c_int) ,dimension(:),allocatable :: array integer(c_int) :: n, ret interface integer(c_int) function alloc(array,n) bind(c) import integer(c_int), dimension(:), allocatable :: array integer(c_int), value :: n end function end interface n=20 ret = alloc(array,n) print *,array deallocate(array) end program foo
Still can't make in polymorphic, though.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
I am not worry about polymorphic at all, and since the library design in C does not depend on me, all i have is a C wrapper and i could use it to assign the base_addr ,CFI_ssetpointer ?
I will do some more test and get familiar with the new CFI functions.
Thanks.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
The way you'd have to do this with CFI_setpointer is to create a separate C descriptor with CFI_establish, that points to malloced storage, and then use CFI_setpointer to do the pointer assign. It would then be not allowed to deallocate it in Fortran nor could you make this an allocatable.
You aren't allowed to modify the base_addr component yourself.