问题
I mainly tried to mimic this in an even simpler setting. No luck.
I wrote a simple fortran code :
      subroutine POWERTWO (n, nsquared)
      !DEC$ ATTRIBUTES DLLEXPORT :: POWERTWO
      integer, intent(in) :: n
      integer, intent(out) :: nsquared
      nsquared = n*n
      return
      end subroutine POWERTWO
that I compiled with gfortran as follows :
gfortran -m32 -dynamiclib ./tmp.f90 -o ./tmp.dylib
Note that my gfortran is configured as follows :
COLLECT_LTO_WRAPPER=/usr/local/lvm/gcc-5.2.0/libexec/gcc/x86_64-apple-darwin14.4.0/5.2.0/lto-wrapper
Target: x86_64-apple-darwin14.4.0
Configured with: ../configure --prefix=/usr/local/lvm/gcc-5.2.0 --enable-checking=release --with-gmp=/usr/local/lvm/gmp-6.0.0 --with-mpfr=/usr/local/lvm/mpfr-3.1.2 --with-mpc=/usr/local/lvm/mpc-1.0.3 --enable-languages=c,c++,fortran,objc,obj-c++ --with-isl=/usr/local/lvm/isl-0.14 --with-cloog=/usr/local/lvm/cloog-0.18.4
Thread model: posix
gcc version 5.2.0 (GCC)
In the same folder where the dylib is, I have an excel 2011 xslm spreadsheet, and in the VBA I put the following code :
Declare Function powertwo CDecl Lib "tmp.dylib" (n As Long, ByVal nsquared As Long)
Function VBA_UDFPowerTwo(n As Long) As Long
    Dim res As Long
    res = 0
    Call powertwo(n, res)
    VBAUDFPowerTwo = res
End Function
Now, doing in cell A2 the formula =VBA_UDFPowerTwo(A1) gives me a #VALUE!. Same result if I put the whole path to the dylib in the VBA as :
Declare Function powertwo CDecl Lib "/Users/XXXXXX/Documents/GITHUBRepos/DYLIBS/MyFirstDylib/tmp.dylib" (n As Long, ByVal nsquared As Long)
or as
Declare Function powertwo CDecl Lib "Mackintosh HD:Users:XXXXXX:Documents:GITHUBRepos:DYLIBS:MyFirstDylib:tmp.dylib" (n As Long, ByVal nsquared As Long)
and same if I replace ByVal by ByRef. Even a
Declare Function powertwo CDecl Lib "Mackintosh HD:Users:ludwigvonmises:Documents:GITHUBRepos:DYLIBS:MyFirstDylibt:tmp.dylib" Alias "POWERTWO" (n As Long, ByRef nsquared As Long)
did not make my day. Am I missing something or doing something wrong ?
I did a nm on the dylib an get the following :
00000fa4 t ___x86.get_pc_thunk.ax
00000f87 T _powertwo_
         U dyld_stub_binder
whereas nm -gU gives me :
00000f87 T _powertwo_
Console.app told me the following while excel was opened and calculation in the A2 cell triggered :
22/08/15 19:37:32,892 Microsoft Excel[2971]: WARNING: The Gestalt selector gestaltSystemVersion is returning 10.9.5 instead of 10.10.5. Use NSProcessInfo's operatingSystemVersion property to get correct system version number.
Call location:
22/08/15 19:37:32,892 Microsoft Excel[2971]: 0   CarbonCore                          0x96a01291 ___Gestalt_SystemVersion_block_invoke + 135
22/08/15 19:37:32,893 Microsoft Excel[2971]: 1   libdispatch.dylib                   0x92c4f0b5 dispatch_once_f + 251
22/08/15 19:37:32,893 Microsoft Excel[2971]: 2   libdispatch.dylib                   0x92c500d8 dispatch_once + 31
22/08/15 19:37:32,893 Microsoft Excel[2971]: 3   CarbonCore                          0x9697a69d _Gestalt_SystemVersion + 1050
22/08/15 19:37:32,893 Microsoft Excel[2971]: 4   CarbonCore                          0x969797c0 Gestalt + 150
22/08/15 19:37:32,893 Microsoft Excel[2971]: 5   MicrosoftComponentPlugin            0x01bdb27e McpInitLibrary_ + 505
22/08/15 19:37:32,893 Microsoft Excel[2971]: 6   MicrosoftComponentPlugin            0x01bdb0ae McpInitLibrary_ + 41
and otool -L tmp.dylib showed the following :
./tmp.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lvm/gcc-5.2.0/lib/i386/libgfortran.3.dylib (compatibility version 4.0.0, current version 4.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
    /usr/local/lvm/gcc-5.2.0/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/local/lvm/gcc-5.2.0/lib/i386/libquadmath.0.dylib (compatibility version 1.0.0, current version 1.0.0)
EDIT
Resorting to :
Declare Function powertwo_ CDecl Lib "Macintosh HD:Users:XXXXXX:Documents:GITHUBRepos:DYLIBS:MyFirstDylib:tmp.dylib" (n As Long, ByRef nsquared As Long)
as Ken Thomases suggested, made excel crash when calculation triggered in cell A2, which shows at least that the exported function name is not powertwo but powertwo_, and that excel's VBA loads tmp.dylib indeed.
回答1:
Your attempt at doing this had a few issues:
- mismatch in the procedure arguments - Fortran passes by reference by default, as does VBA. In your multiple attempts at getting the interface right you didn't quite match them up. 
- mismatch in the procedure return value - Your Fortran procedure is a subroutine, which returns no value. You need to declare the VBA procedure as a - Sub, not a- Function.
- Use of Intel Fortran directives - The - !DEC$directives (afaik) are just comments to gfortran and not interpreted.
Here is what I've done, and tested that it works.  The Fortran has been re-written using the iso_c_binding C-interop features of Fortran 2003 to give more control over the exported procedure interface and ensure that you get what you want.  You are using a modern Fortran compiler, so this is not an issue for you.
The Fortran:
subroutine POWERTWO (n, nsquared) bind(C, name='powertwo')
  use iso_c_binding, only: c_long
  implicit none
  integer(kind=c_long), intent(in) :: n
  integer(kind=c_long), intent(out) :: nsquared
  nsquared = n*n
  return
end subroutine POWERTWO 
This will produce an procedure with the C interface
void powertwo(long int* n, long int* squared)
I compiled this with gfortran 5.2 (from macports):
gfortran-mp-5 -m32 -dynamiclib -o test32.dylib test.f90
In Excel VBA, I have declared the procedure as:
Declare Sub powertwo CDecl Lib "/Users/casey/code/so/xlstest/test32.dylib" (ByRef n As Long, ByRef nsquared As Long)
Function VBA_UDFPowerTwo(n As Long) As Long
    Dim res As Long
    res = 0
    Call powertwo(n, res)
    VBA_UDFPowerTwo = res
End Function
Note the above also fixes a typo in your line VBAUDFPowerTwo = res, which is missing an underscore after VBA (doesn't match the Function name).  I have also changed the imported function to be a Sub and explicitely declared its arguments as ByRef (which should be the default).
This produces the desired behavior:
来源:https://stackoverflow.com/questions/32158814/c-dylib-curiously-not-found-by-excels-2011-vba-on-mac