- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why can I link my Intel Fortran dll (sum_if.dll) to my Fortran (sum_test) but not my C++ one (sum_cpp.dll)? All are accepted as STDCAL DLLs by other software e.g. Excel VBA (in the attached .zip)
Fortran Linking to sum_if works with any of:
- Linker | Input | Additional Dependecies= sum_if.lib
- Adding.lib to project (e.g. sum_if.lib)
- Project Dependencies = sum_if
But for sum_cpp the dll is not found or accepted i.e.
sum_test.obj : error LNK2019: unresolved external symbol __imp_sum referenced in function _MAIN__
Dependency Walker shows function=sum on both. So hopefully it is not a "Decoration" issue?
I have attached the VS Community 2013 Solution, as I hope/ expect the answer is hidden there.
1. VS 2013 Solution= sumdll Projects: = Win32,
All sharing same ..\Output\Release and Debug directories. The excel “double check” lives in Debug. This helps simplify and clarify "finding" the DLL (I wanted to avoid full paths)
1.1 Sum_if.dll contains:
function sum(a,b) IMPLICIT NONE ! Expose subroutine ExcelDLL to users of this DLL !DEC$ATTRIBUTES STDCALL, DLLEXPORT, ALIAS: 'sum' :: sum !DEC$ATTRIBUTES Value :: a,b ! Variables integer*4 a,b,sum ! Body of ExcelDLL sum=a+b end function sum
1.2 Sum_cpp.dll
// Sum_cpp.cpp contains: int _stdcall sum(int x, int y){ return x+y; } // Sum_cpp.def contains: LIBRARY "sum_cpp"" EXPORTS sum @
1.3 Sum_test
Interface function sum(a,b) IMPLICIT NONE ! Expose subroutine ExcelDLL to users of this DLL !DEC$ ATTRIBUTES DLLIMPORT, ALIAS:'sum' :: sum !DEC$ATTRIBUTES Value :: a,b ! Variables INTEGER*4 a,b,sum end function sum End Interface INTEGER*4 :: a_i4b, b_i4b, c_i4b,d_i4b, I, j print *, 'add integers' a_i4b=7 b_i4b=43 c_i4b=sum(a_i4b,b_i4b) write(*,'(I10,A,I10,A,I10)') a_i4b," + ", b_i4b," = ",c_i4b end program vf_dll_test
2. Excel VBA Declares
' all work fine: ' C++ Declare Function sumcpp Lib "sum_cpp.dll" Alias "sum" (ByVal i As Long, ByVal j As Long) As Long ' Intel Fortran 10.1 Declare Function sumif Lib "sum_if.dll" Alias "sum" (ByVal a As Long, ByVal b As Long) As Long
Peter
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For what it is worth, here is a complete zip of the source files and a batch file to produce a DLL and an EXE that uses the DLL. Open an IFort - 32 bit command window, and run the batch file.
s:\lang\sumdll\sum_cpp\tst>bld s:\lang\sumdll\sum_cpp\tst>lib /def:sum_cpp.def /machine:i386 Microsoft (R) Library Manager Version 12.00.31101.0 Copyright (C) Microsoft Corporation. All rights reserved. Creating library sum_cpp.lib and object sum_cpp.exp s:\lang\sumdll\sum_cpp\tst>icl /LD sum_cpp.cpp sum_cpp.exp Intel(R) C++ Compiler XE for applications running on IA-32, Version 15.0.4.221 Build 20150407 Copyright (C) 1985-2015 Intel Corporation. All rights reserved. sum_cpp.cpp Microsoft (R) Incremental Linker Version 12.00.31101.0 Copyright (C) Microsoft Corporation. All rights reserved. -out:sum_cpp.dll -dll -implib:sum_cpp.lib sum_cpp.obj sum_cpp.exp s:\lang\sumdll\sum_cpp\tst>ifort sum_test.f90 sum_cpp.lib Intel(R) Visual Fortran Compiler XE for applications running on IA-32, Version 15.0.4.221 Build 20150407 Copyright (C) 1985-2015 Intel Corporation. All rights reserved. Microsoft (R) Incremental Linker Version 12.00.31101.0 Copyright (C) Microsoft Corporation. All rights reserved. -out:sum_test.exe -subsystem:console -incremental:no sum_test.obj sum_cpp.lib s:\lang\sumdll\sum_cpp\tst>sum_test add integers 7 + 43 = 50
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You will get the C++ name decoration, which will not link correctly with Fortran, unless you surround the declaration of the extern function in C++ with
extern "C" {
...
}
Since, in the Fortran part, you used ALIAS, you have suppressed the usual @nnn decoration that comes with STDCALL, so you will have to provide suitable aliases on the C/C++ side as well.
Note also that you have provided an incorrect interface block in sum_test.f90. You should add the stdcall attribute to the imported symbol. Without that, your program will build with no error messages but the EXE will probably crash with access errors, particularly if optimizations are enabled during compilation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Mecej4
My apologies and thanks: I had eliminated the STDCALL as an experiment and, yes, it does crash after running. Now fixed.
Are you suggesting..?
extern "C" { int _stdcall sum(int x, int y){ return x + y; } }
It did not seem to make a difference. As I said, both DLLs seem undecorated ("sum") in Dependency Walker. So should I still pursue your suggestion further?
Attached is the Release directory in full , inc .dll, lib. (without extern "c" mod)
Sumtest.exe will look for sum_if.dll. But, with appropriate copying and renaming, will run OK with "sum_cpp.dll. It looks to me like the answer lies in the "sum_cpp.lib" file?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Each language compiler/linker package has its own ways of naming external symbols and calling conventions. I do not use VBA or Excel, so I will not comment about what they require, but those are well-documented. There would be less confusion if you defined your objectives precisely instead of attempting some of the many possible combinations.
The dumpbin utility is very helpful in ascertaining the decorated name present in the OBJ, DLL and EXE files.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Mecej4
It is never easy summarizing questions clearly. But I am pleased with mine: i.e.
>>Why can I link my Intel Fortran dll (sum_if.dll) to my Fortran (sum_test) but not my C++ one (sum_cpp.dll)? All are accepted as STDCALL DLLs by other software e.g. Excel VBA (in the attached .zip)
I choose STDCALL throughout. Some others may have found it useful to demonstrate that both DLLs worked fine in Excel. Though I later pointed (in my last email) out that the DLL can be run with the fortran with suitable name changing.
Can anyone else please help? As you may guess, my real problem is less trivial but cannot be continued until I crack this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your C++ routine will have an external name of _sum@8. You need to use the appropriate C++ pragma to change that to "sum". I don't know what that would be offhand.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve
Before I study daunting #pragma stuff..:
If Dependency Walker shows "sum" [and no mangling] and the DLL works as "sum" in Excel, Mathematica and even Fortran (exe but not linking) is this really a name mangling issue?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes. Dependency Walker will lie about things like this. Do a "dumpbin -exports" on the export library and see what you get.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For what it is worth, here is a complete zip of the source files and a batch file to produce a DLL and an EXE that uses the DLL. Open an IFort - 32 bit command window, and run the batch file.
s:\lang\sumdll\sum_cpp\tst>bld s:\lang\sumdll\sum_cpp\tst>lib /def:sum_cpp.def /machine:i386 Microsoft (R) Library Manager Version 12.00.31101.0 Copyright (C) Microsoft Corporation. All rights reserved. Creating library sum_cpp.lib and object sum_cpp.exp s:\lang\sumdll\sum_cpp\tst>icl /LD sum_cpp.cpp sum_cpp.exp Intel(R) C++ Compiler XE for applications running on IA-32, Version 15.0.4.221 Build 20150407 Copyright (C) 1985-2015 Intel Corporation. All rights reserved. sum_cpp.cpp Microsoft (R) Incremental Linker Version 12.00.31101.0 Copyright (C) Microsoft Corporation. All rights reserved. -out:sum_cpp.dll -dll -implib:sum_cpp.lib sum_cpp.obj sum_cpp.exp s:\lang\sumdll\sum_cpp\tst>ifort sum_test.f90 sum_cpp.lib Intel(R) Visual Fortran Compiler XE for applications running on IA-32, Version 15.0.4.221 Build 20150407 Copyright (C) 1985-2015 Intel Corporation. All rights reserved. Microsoft (R) Incremental Linker Version 12.00.31101.0 Copyright (C) Microsoft Corporation. All rights reserved. -out:sum_test.exe -subsystem:console -incremental:no sum_test.obj sum_cpp.lib s:\lang\sumdll\sum_cpp\tst>sum_test add integers 7 + 43 = 50
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Many thanks mecej4, that is excellent.
I can see (from dumpbin) that you have managed the remove all name-mangling from the dll and lib, so my Fortran happily links to it.
Your sum_cpp.def, with "sum=_sum@8" is an easy and effective solution and I much recommend anyone interested in removing the C++ name-mangling to download your example in full!
Bravo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am not a fan of using .def files in this way. It will prevent you from building from x64. Better would be to remove STDCALL from the equation and use the Fortran C interoperability features, though if you need STDCALL we now allow you to use ATTRIBUTES STDCALL with BIND(C).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve, I agree with you in principle, but in this case the problem was with the C/C++ compiler. MS does not provide an "alias" pragma to control underscores and other decorators. GCC does, but then, ... So, with MS C, you have to pick from the attributes available, and adjust the names generated in the other OBJ files to suit. I suppose you could consider syscall, fastcall, etc.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve #11
I plan to eventually use Fortran C interoperability features, but for now DLLs are useful.
Steve>> using .def files in this way .. will prevent you from building from x64
What is the issue with DEF in x64? Is it just that one needs a different DEF file as it seems x64 un-mangles with just “sum” not “sum=_sum@8 ?
Steve>> we now allow you to use ATTRIBUTES STDCALL with BIND(C).
Can you please give me more details? Would this allow Fortran to link to an STDCALL DLL despite mangled-names?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you want to create a 64-bit version of your DLL to be callable from 64-bit Excel? Does 64-bit Excel use STDCALL? These may well be "I'll look at it later" types of questions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Excel is not the reason I wish to support STDCALL for now.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page