Вызов функции / подпрограммы C в коде Фортрана

Я пытаюсь скомпилировать и связать код Fortran, вызывающий подпрограмму c:

Код Фортрана:

program adder
integer a,b
a=1
b=2
call addnums(a,b)
stop    
end program

Код C:

void addnums( int* a, int* b ) 
{
    int c = (*a) + (*b);  /* convert pointers to values, then add them */
    printf("sum of %i and %i is %i\n", (*a), (*b), c );
}

Я использовал следующие команды для компиляции и ссылки в среде Windows.

ifort -c adder.f
cl -c addnums.c
ifort -o add adder.obj addnums.obj

Я получаю следующую ошибку:

Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.
-out:add.exe 
-subsystem:console 
adder.obj 
addnums.obj 
adder.obj : error LNK2019: unresolved external symbol ADDNUMS referenced in function MAIN__
add.exe : fatal error LNK1120: 1 unresolved externals

Пожалуйста, помогите мне решить эту проблему? Благодарю.

2 ответа

Вам необходимо предоставить тело интерфейса для функции C внутри части спецификации основной программы Fortran, которая сообщает компилятору Fortran, что имя addnums является функцией C. Что-то вроде:

INTERFACE
  SUBROUTINE addnums(a, b) BIND(C)
    USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT
    IMPLICIT NONE
    INTEGER(C_INT) :: a, b
  END SUBROUTINE addnums
END INTERFACE

(С этими компиляторами на этой платформе без специальных опций целочисленный тип по умолчанию такой же, как C_INT - но явное указание на целое число KIND помогает защитить вас в случае изменения параметров компилятора / платформы или компиляции.)

Вот две вещи, которые я вижу сразу (я работаю в основном с FORTRAN77, так что это может быть не самым новым или лучшим способом сделать это):

  1. Так как ваша функция C - это функция (а не подпрограмма), вам нужно объявить 'addnums' как EXTERNAL. Добавьте это к своему коду в разделе объявлений.

    EXTERNAL addnums
  2. Добавьте подчеркивание к имени функции в вашем C-коде. FORTRAN делает это автоматически для своих собственных функций, но не для функций на других языках. Таким образом, подпись функции будет

    void addnums_( int* a, int* b )

Эта страница имеет довольно хорошее краткое изложение по смешиванию C и FORTRAN. Надеюсь, это помогло!

Другие вопросы по тегам