Como acessar (alocados dinamicamente) matrizes Fortran em C

Minha principal questão é por que os arrays fazem coisas tão estranhas e se existe alguma maneira de fazer o seguinte de uma maneira "limpa".

Atualmente tenho um programa em Cfoo.c interface de um programa Fortranbar.f90 através dadlopen/dlsym, mais ou menos como no código abaixo:

foo.c:

#include <dlfcn.h>
#include <stdio.h>

int main()
{
int i, k = 4;
double arr[k];
char * e;

void * bar = dlopen("Code/Test/bar.so", RTLD_NOW | RTLD_LOCAL);

void (*allocArray)(int*);
*(void **)(&allocArray) = dlsym(bar, "__bar_MOD_allocarray");
void (*fillArray)(double*);
*(void **)(&fillArray) = dlsym(bar, "__bar_MOD_fillarray");
void (*printArray)(void);
*(void **)(&printArray) = dlsym(bar, "__bar_MOD_printarray");
double *a = (double*)dlsym(bar, "__bar_MOD_a");

for(i = 0; i < k; i++)
    arr[i] = i * 3.14;

(*allocArray)(&k);
(*fillArray)(arr);
(*printArray)();
for(i = 0; i < 4; i++)
    printf("%f ", a[i]);
printf("\n");

return 0;
}

bar.f90:

module bar

integer, parameter :: pa = selected_real_kind(15, 307)
real(pa), dimension(:), allocatable :: a
integer :: as

contains

subroutine allocArray(asize)
    integer, intent(in) :: asize

    as = asize
    allocate(a(asize))

    return
end subroutine

subroutine fillArray(values)
    real(pa), dimension(as), intent(in) :: values

    a = values
    return
end subroutine

subroutine printArray()
    write(*,*) a
    return
end subroutine

end module

Executando rendimentos principais

0.0000000000000000        3.1400000000000001        6.2800000000000002        9.4199999999999999     
0.000000 -nan 0.000000 0.000000 

que mostra que Fortran aloca a matriz corretamente e até mesmo armazena corretamente os valores fornecidos, mas eles não são mais acessíveis via dlsym (trabalhando nos resultados de dados em segfaults). Eu também tentei isso para matrizes de tamanho fixo - os resultados permanecem os mesmos.

Alguém sabe o motivo desse comportamento? Eu, pessoalmente, teria esperado que as coisas funcionassem bidirecionalmente ou alternativamente de forma alguma - este "Fortran aceitando C arrays mas não vice-versa" me faz pensar se há algum erro básico que cometi ao acessar o array do C dessa maneira.

A outra (e ainda mais importante) questão é como fazer acessos de matriz como esses "o caminho certo". Atualmente, não tenho certeza se manter a interface "Fortran as .so" é uma boa maneira - acho que também seria possível tentar uma programação mista nesse caso. No entanto, a questão dos arrays permanece - eu li que isso poderia ser resolvido de alguma forma usando o ISO C Binding, mas eu não consegui descobrir como, ainda (eu não trabalhei muito com Fortran, ainda, especialmente com o referido Binding) Então, ajuda sobre esta questão seria muito apreciada.

Editar:

Ok, então eu li na ISO C Binding um pouco mais e encontrei uma abordagem bastante útilAqui. UsandoC_LOC Eu posso obter ponteiros C para minhas estruturas Fortran. Infelizmente, os ponteiros para matrizes parecem ser ponteiros para ponteiros e precisam ser desreferenciados no código C antes que possam ser tratados como matrizes C - ou algo parecido.

Editar:

Peguei meu programa para funcionar agora, usando o encadernamento em C do jeito que Vladimir F apontou, pelo menos na maior parte. O arquivo C e os arquivos Fortran agora estão interligados, então eu posso evitar a interface libdl, pelo menos para a parte Fortran - eu ainda preciso carregar uma biblioteca C dinâmica, pegar um ponteiro de função para um dos símbolos lá e passar isso como um ponteiro de função para Fortran, que posteriormente chama essa função como parte de seu cálculo. Como a referida função espera double * s [arrays], eu não consegui passar meus arrays Fortran usando C_LOC, estranhamente - nenhumC_LOC(array) nemC_LOC(array(1)) passou os ponteiros corretos de volta para a função C.array(1) fez o truque embora. Infelizmente, essa não é a maneira mais "limpa" de fazer isso. Se alguém tem uma dica para mim como fazer isso usando oC_LOC função, isso seria ótimo. No entanto, aceito a resposta de Vladimir F, pois considero que é a solução mais segura.

questionAnswers(2)

yourAnswerToTheQuestion