Fortran90 и размер массивов, созданных в C++

Я пытаюсь вызвать код Fortran 90 из основной программы C++. Подпрограмма Fortran принимает в качестве параметра массив значений типа double (назовем его X), а затем продолжает использовать size(X) во многих местах кода. Я вызываю подпрограмму с массивом C, созданным с помощью

double *x = new double[21]

но когда я печатаю результат size(X) в коде Fortran, я получаю 837511505 или какие-то другие большие числа.

Прямо сейчас я могу изменить код на Фортране, так что в худшем случае нужно переписать функцию, передав размер в качестве параметра. Но я бы предпочел этого не делать.

Кто-нибудь знает, есть ли способ создать массив C таким образом, чтобы подпрограмма Fortran могла определить его размер?


person Alain    schedule 23.03.2012    source источник
comment
Навскидку, вероятно, Fortran ожидает, что размер массива хранится где-то в памяти относительно указателя, который вы передаете, но C++ не обязывает этого.   -  person quant_dev    schedule 24.03.2012


Ответы (3)


Это особенность реализации. Многие реализации (например, RSX и OpenVMS) определяют структуру для передачи указателя на данные, а также описание измерений, типов и т. д. Другие реализации не передают ничего подобного, если внешнее объявление явно не вызывает механизм для генерации дескриптор. Большинство других не предоставляют такого механизма.

Не зная, какая реализация используется:

а) прочтите документацию к компилятору
б) попросите компилятор сгенерировать сборку и проверьте ее, чтобы узнать, что он ожидает

person wallyk    schedule 23.03.2012
comment
Спасибо за ответ. Вероятно, будут использоваться компиляторы Intel и GNU, и только для второстепенных частей проекта. Если я в конечном итоге буду использовать код Fortran, я, вероятно, просто напишу вокруг него оболочку. - person Alain; 26.03.2012

Intel F95 использует структуру дескриптора массива, которая помимо указателя массива также хранит информацию о границах и размерах. size() получает информацию из дескриптора.

Поскольку вы передаете только указатель C, информация о дескрипторе недоступна, поэтому size() возвращает тарабарщину.

Как правило, вы находитесь на сложной территории программирования на смешанных языках, где массивы и структуры часто являются головной болью программиста. В документе пользователя компилятора Intel есть отдельный раздел о смешанном вызове C‹=>F95.

В частности, проверьте интерфейсы и привязку — приятная функция F95, помогающая в межъязыковых вызовах.

Хорошая новость: вызов C‹=>F95 работает очень хорошо, если вы придерживаетесь соглашений.

person vmsnomad    schedule 08.06.2012

Я лично использую массу смешанного кодирования от C++ до Fortran 90/95/2003. Обычно я использую gfortran в качестве компилятора, но чтобы избежать этой проблемы, обычной практикой является всегда отправлять размер массивов. Это позволяет даже изменить форму. Рассмотрим двумерный массив, содержащий точки x, y:

double* x = new double[2*21]

real(8),intent(in),dimension(2,21)::x

Это очень удобная функция, которая позволит вам использовать команду размера. Ответы о специфике компилятора верны. Чтобы ваш код можно было использовать в большинстве компиляторов, вы должны указать длину при использовании многоязычных интерфейсов.

person David Folkner    schedule 13.06.2012