процедура импорта интерфейсного модуля из фортрана в C

Как мне импортировать fortran interface в C, используя extern?

Предположим, у меня есть следующий модуль fortran:

!swapper module
module swapper
   interface swap
      module procedure swap_r, swap_i, swap_c
   end interface
contains
    !subroutine implementations here:
    !swap_r takes two double precision as argument
    !swap_i takes two integers as argument
    !swap_c takes two characters as argument
end module swapper

Тогда я могу просто сделать в C следующее?

extern "C" void __swapper_MOD_swap(double*, double*)
extern "C" void __swapper_MOD_swap(int*, int*)
extern "C" void __swapper_MOD_swap(char*, char*)

В качестве альтернативы, если я обещаю вызывать swap только с числами двойной точности, могу ли я делать это исключительно?

extern "C" void __swapper_MOD_swap(double*, double*)

person QuantumDot    schedule 14.06.2017    source источник
comment
Возможно, это поможет вам, docs.cray .com/books/S-2179-52/html-S-2179-52/ppgzmrwh.html.   -  person Stargateur    schedule 14.06.2017
comment
В C нет дженериков. Но в C++ есть дженерики. И в C нет extern "C". Вы действительно используете C++?   -  person Vladimir F    schedule 14.06.2017
comment
Здесь содержится дополнительная информация об «ИНТЕРФЕЙСЕ»: people.sc.fsu. edu/~jburkardt/f_src/f90_calls_c++/   -  person QuantumDot    schedule 15.06.2017


Ответы (1)


Похоже, вы на самом деле используете C++. Но сначала давайте ответим для C или C++ в стиле C:

Нет, вы не можете сделать

extern "C" void __swapper_MOD_swap(double*, double*)

вы не можете сделать это для трех разных типов аргументов, вы не можете сделать это даже для одного типа аргументов.

На самом деле в библиотеке вообще не должно быть __swapper_MOD_swap.

Что делает Fortran, так это то, что он сохраняет интерфейс (который является просто описанием того, как что-то вызывать) для трех конкретных подпрограмм swap_r, swap_i, swap_c и позволяет вам вызывать их по имени swap.

Но в модуле НЕТ реальной подпрограммы swap!!! Фортран просто позволит вам назвать эти три особенности под другим именем, вот и все.

Невозможно вызвать эти функции из C как универсальный. C не имеет такого типа обобщений! (в нем есть некоторые функции, которые работают с любым типом, использующим void*).


В C++ вы действительно можете создавать дженерики, специализированные для различных типов, и вы можете вызывать процедуры Fortran как дженерики, но вы должны сами сообщить об этом C++! Вы можете создать шаблон и вручную настроить этот шаблон для вызова соответствующих extern "C" функций.

Для примера см. мой заголовок https://github.com/LadaF/PoisFFT/blob/master/src/poisfft.h, где я создаю класс C++, связанный с функциями extern "C" struct и некоторыми функциями extern "C", которые, однако, все реализованы на Фортране.


Наконец, НЕ используйте символы __swapper_MOD_. Создайте некоторую привязку Fortran, используя bind(C,name="some_name"), и вызовите от some_name до extern "C", потому что разные компиляторы Fortran ДЕЙСТВИТЕЛЬНО используют разные схемы искажения имен.

person Vladimir F    schedule 14.06.2017
comment
Спасибо за ваш подробный ответ, включая советы по передовым методам! - person QuantumDot; 14.06.2017