2016-12-28 9 views
1

Я пытаюсь написать некоторые числовые функции в Fortran, к которым позже можно получить доступ в Excel. Я использую Office 2013 (64-разрядная версия), Visual Studio 2015 «Сообщество» и Intel Fortran (Intel Parallel Studio XE 2017); и я могу правильно скомпилировать исполняемые программы. Я также могу генерировать DLL-файлы, которые, как я полагаю, являются правильными.Написание DLL в Fortran/вызов из Excel

Вот минимальный Fortran пример кода, я работал из this tip:

function id(x) 
    !DEC$ ATTRIBUTES DLLEXPORT :: id 
    integer :: id, x 
    id = x 
    return 
end function 

и у меня есть это на стороне Excel под кодом VBA для Лист1:

Option Explicit 
Option Base 1 
Public Declare PtrSafe _ 
    Function id Lib "mydll.dll" _ 
    (ByVal x As Integer) As Integer 

Делая это , Мне удается иметь формулу в Excel для автоматического заполнения имени функции, но при оценке любого экземпляра ячейка мгновенно начнет мигать 0, а затем поверните #VALUE !.

Я пробовал несколько вещей в комбинаторной/грузовой культовой моде: используйте ByRef вместо ByVal, имеют функции использовать только целые или одноточечные (реальные * 4) или двухточечные (реальные * 8) поплавки и то вещи, которые делают еще меньше смысла.

У меня наконец-то закончились комбинации случайных ключей для пюре, и очень мало источников, покрывающих этот конкретный прецедент. Если я должен кипеть это вниз к чему-то более точным, чем «что делать дальше»:

  • у меня возникают проблемы из-за числовых типов или что-то связанные с «несоответствия импеданса» между мирами Фортрана и Excel?
  • Я не пропускаю необходимый шаблон, код клея и т. Д.?

ответ

1

Кажется, вы не подозреваете, что Intel Fortran предоставляет несколько примеров совместимости Excel/VBA и Fortran. Загрузите пакет Intel Parallel Studio XE для Windows Sample Bundle с https://software.intel.com/en-us/product-code-samples. В файле ZIP файл compiler_f \ MixedLanguage \ Excel, вероятно, наиболее важен для вас. Важным аспектом является то, что любые вызовы из VBA должны указывать механизм вызова STDCALL на вызываемой стороне процедуры, иначе вы получите повреждение стека.

0

Вот фрагмент из справочных файлов Intel для визуальных файлов Fortran.

subroutine FortranCall (r1, num) 
    !DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE, ALIAS:"FortranCall" :: FortranCall 
    integer, intent(in) :: r1 
    character(10), intent(out) :: num 
    !DEC$ ATTRIBUTES REFERENCE :: num 

    num = '' 
    write (num,'(i0)') r1 * 2 

return 
end subroutine FortranCall 

А на стороне первенствовать они использовали:

Declare Sub FortranCall Lib "C:\Temp\Fcall.dll" (r1 As Long, ByVal num As String) 

Это будет хорошо, чтобы получить больше примеров с различными входами и выходами, чтобы помочь пользователям.