2013-08-05 9 views
2

Я использую gfortran-компилятор (под Simply Fortran) для Windows 64 и при создании базовой fortran dll для тестирования я не могу запустить его под VBA и получил ошибку времени выполнения 48: DLL не может быть найдена.вызов fortran dll из VBA

вот мой Фортран код подпрограммы:

subroutine multiply(x, y, z) 

!DEC$ ATTRIBUTES DLLEXPORT :: multiply 
!DEC$ ATTRIBUTES ALIAS : "multiply" :: multiply 

real, intent(in):: x, y 
real, intent(out):: z 

z = x * y 

end subroutine multiply 

Я создаю библиотеку набрав: gfortran -shared -omultiply.dll multiply.f90 эта библиотека находится в «C: \ Users \ Olivier \ Documents \ Fortran \»

и мой код VBA (я использую VBA 7.0):

Declare Sub multiply Lib "C:\Users\Olivier\Documents\Fortran\multiply.dll" (x As Single, y As Single, ByRef z As Single) 

Sub test() 

Dim x As Single 
Dim y As Single 
Dim z As Single 

x = 2 
y = 3 

Call multiply(x, y, z) 

Cells(1, 1) = z 

End Sub 

При выполнении этого кода VBA, он говорит, что не может найти multiply.dll где а Этот файл находится в правильном файле, указанном в декларации, если кто-то может помочь!

Спасибо заранее

+0

У вас есть эта ссылка: http://stackoverflow.com/questions/8606740/vba-cannot-find-my-dll-despite-hardcoding-location? – varocarbas

+0

Также, чтобы уменьшить источники ошибок, я бы поместил dll в ту же директорию, что и таблица, и уменьшил имя до «multiply.dll». – varocarbas

+0

. Я попытался поместить dll в ту же директорию, что и файл excel, но он не сделал К сожалению, ничего не изменит. – Olivier

ответ

0

Пытались ли вы с LoadLibrary-API?

Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (_ 
    ByVal lpLibFileName As String) As Long 

Declare Sub multiply Lib "multiply.dll" (_ 
    x As Single, _ 
    y As Single, _ 
    ByRef z As Single) 

'Call LoadLibrary ONCE!!!! before calling 'multiply', e.g. on opening the workbook 
LoadLibrary "C:\Users\Olivier\Documents\Fortran\multiply.dll" 

С уважением,

AKDA

+0

Похоже, хорошая идея, но я понятия не имею, как создать такую ​​функцию LoadLibrary :( – Olivier

+0

ok LoadLibrary - это функция, включенная в библиотеку kernel32, извините, я не понимал, что, поскольку я никогда не использовал ее, я сделал это как вы сказали, но я все равно получаю ту же ошибку 53, он не может найти multiply.dll :( – Olivier

+0

Вы изменили объявление метода умножения, как я сделал в примере, удалив путь и просто поместив ** Lib "multiply.dll "** как источник? Вы также должны проверить возвращаемое значение LoadLibrary (должно быть <> 0) и Err.LastDLLError (должно быть 0), возможно, ваша DLL не может быть загружена в первую очередь. Я использую этот метод для вызывающие функции из C++ - DLL, созданные в Visual Studio в MS Access, и работают 100% **, если ** DLL может быть загружена правильно. – AKDADEVIL

0

My Excel 2010 является действительно 32-битная версия, так что я построил 32-бит DLL умножить STDCALL:

subroutine multiply(x, y, z) 

    !GCC$ ATTRIBUTES STDCALL :: multiply 

    real , intent (in) :: x, y 
    real , intent (inout) :: z 

    z = x * y 

end subroutine multiply 

, когда я откройте эту DLL с Dependency Walker, она говорит, что не может найти LIBGCC_S_SJLJ-1.DLL, я понятия не имею, как решить эту проблему с помощью ALIAS и при работе под VBA я получаю runtim e error 53 теперь, пожалуйста, если кто-нибудь может помочь, это далеко за пределами моих возможностей, было так легко связать fortran dll под R, я бы никогда не думал, что так сложно делать то же самое под VBA :(

+0

* LIBGCC_S_SJLJ-1.DLL * находится в * bin * каталог MinGW, juste добавьте этот каталог в [системный путь] (http://windowsitpro.com/systems-management/how-can-i-add-new-folder-my-system-path) и перезапустите Excel. –

0

У меня была такая же проблема, и это беспокоило меня, пока я не нашел решение. Если вы посмотрите на хост зависимостей, то отсутствует ссылка dll, скорее всего, из среды отладки. Шахта была DFORTD.DLL.

Раствор для

  1. Либо компилировать по высвобождению и убедитесь, что все зависимые библиотеки DLL доступны
  2. Или компилировать с статических библиотек /libs:static параметра или для меня, указав в настройках Fortran/Library/Debug Single-threaded.

В конце концов, убедитесь, что нет отсутствующих зависимостей в вашей DLL

Depends

0

Я успешно заселен 2D-массив Long с из функции игрушки DLL, вызова из Excel VBA, используя следующий подход.

Fortran Код:

Subroutine FortranDLL(Array1, dim1, dim2) 
    Implicit None 
    Integer :: dim1, dim2 
    Integer :: Array1(1:dim1, 1:dim2) 
    Integer :: i, j 
    do i=1,dim1 
     do j=1,dim2 
      Array1(i,j)=(10*i) + j 
     end do 
    end do 
    End Subroutine FortranDLL 

Составлено с использованием Code :: Blocks с:

mingw32-gfortran.exe -Jobj\Release\ -mrtd -fno-underscoring -Wall -DBUILD_DLL -O2  -c D:\Test2\main.f95 -o obj\Release\main.o 
    mingw32-gfortran.exe -shared -Wl,--output-def=bin\Release\libTest2.def -Wl,--out-implib=bin\Release\libTest2.a -Wl,--dll obj\Release\main.o -o bin\Release\Test2.dll -s 

Примечание особенно использование -mrtd и -fno-underscoring при компиляции.

в программе Excel VBA затем:

Option Explicit 
    Option Base 1 

    Declare Sub fortrandll Lib "D:\Test2\bin\Release\Test2.dll" _ 
     (ByRef Array1 As Long, ByRef rows As Long, ByRef cols As Long) 

    Sub TestDLL() 

     Const rows As Long = 7 
     Const cols As Long = 5 

     Dim Arr(1 To rows, 1 To cols) As Long 

     Call fortrandll(Arr(1, 1), rows, cols) 

     ActiveSheet.Range("A1").Resize(rows, cols).Value = Arr 

    End Sub 

Обратите внимание, что первый элемент массива передается в DLL ByRef как обычный Long.

Я благодарен автору here за мои первоначальные указатели на рабочее решение. Очень похожее решение также появляется в строке this comp.lang.fortran.

Смежные вопросы