Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
New Contributor I
178 Views

LIB file linking question

This question applies to Windows, with my fortran app compiled for win32.

  • I am calling a c++ DLL from fortran. 
  • I have the DLL in stdcall and cdecl flavors. 
  • For several reasons, I want to use the stdcall flavor. 
  • I have a LIB file for the cdecl, but not for the stdcall (that's all the vendor has supplied).
  • I use the cdecl LIB file for linking in the stdcall DLL with my fortran app.

So far that seems to work.  But recently, in fortran, I've been getting corrupted stack messages when running in the visual studio debugger, and I am wondering if this could be because of the LIB file.  

Does anyone know if that is possible?

0 Kudos
12 Replies
Highlighted
Black Belt Retired Employee
167 Views

Hard to say. It's unusual to have the STDCALL and CDECL entry points be the same. You do seem to be making things difficult for yourself with all these weird combinations.

Mixing CDECL and STDCALL definitely will lead to stack corruption, and since that's the symptom, it's very likely you aren't using the combination you think you are.

Why do you want to use stdcall? More often than not it's nothing but trouble.

--
Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
New Contributor I
159 Views

It certainly feels like I'm doing things the hard way.  I'm forced into this because the inevitable application is being called from Excel visual basic.  I'm trying to avoid mixing cdecl and stdcall by sticking exclusively to stdcall.  I'm losing the battle. 

I do not want to mix the two, and wouldn't be if I had a LIB file for the stdcall DLL, but I don't, and the vendor says he won't give me one.  So, not knowing any better, instead of giving up, I've tried to use the cdecl LIB, and have had some measure of success.  Maybe I was just lucky, or unlucky.

If I was a wizard at this stuff, there might be a way out of this mess.  But maybe not.  I just don't know.

0 Kudos
Highlighted
Black Belt
148 Views

Applying the requirements around how VBA interacts with your code, to all of your code, seems like a case of tail swinging dog.

Separate interface from implementation.  The interface with VBA on the Fortran side should just be through a thin layer that forwards to the real code, after dealing with the interface specific aspects.

(The situation with the lib file and the DLLs does not make sense to me.  Rather than guessing as to what is going on: Who is the vendor? What is the specific code they are providing?  What documentation have you been given?  What interface source code (header files and the like)?)

0 Kudos
Highlighted
Black Belt
143 Views

Given all this trouble with different calling sequences, 32-bit vs. 64-bit and the amount of wasted effort that we have seen already, I am tempted to ask: Is it foreordained that you must call the Fortran and C++ DLLs from Excel? What purpose does Excel serve in the overall scheme of things? Could your users simply write a text file with data for a particular problem and have the Fortran read that code and provide output solutions as other text files or CSV files?

0 Kudos
Highlighted
Black Belt Retired Employee
131 Views

My guess is that you're using a project-level option to set the calling convention (/iface). Don't do that. For your function that is called from Excel, use !DEC$ ATTRIBUTES STDCALL, REFERENCE on that routine only. For everything else, use the default (CDECL). Don't use the STDCALL version of the DLL.

--
Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
New Contributor I
125 Views

The whole picture is complicated.  There are DLL's from three vendors.  Two provide only stdcall versions.  The third provides both, but for their stdcall version they do not and will not provide a LIB file (wyday.com).  If I could (but I can't), I would eliminate wyday.com from the picture.

I need to call routines in the vendor DLL's from both VBA directly, and from my own c++ and fortran DLL's.

I have spent (wasted?) a lot of time trying to fit a square peg into a round hole.  Now that I know a little more about what not to do, I will devise a new plan.  It will almost surely require mixing stdcall and cdecl conventions.

0 Kudos
Highlighted
New Contributor I
123 Views

For my fortran DLL project, /iface does not appear in the command line, and Properties/Fortran/External Procedures/Calling Convention is Default.

0 Kudos
Highlighted
Black Belt Retired Employee
100 Views

If you're not using /iface, are you using !DEC$ ATTRIBUTES STDCALL anywhere? You can't just arbitrarily choose to call a STDCALL routine if the compiler thinks it is using CDECL.

--
Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
New Contributor II
90 Views

I cannot offer suggestions but as a friend I can say good luck.

0 Kudos
Highlighted
Black Belt
70 Views


@Brian_Murphy wrote:

The whole picture is complicated.  There are DLL's from three vendors.  Two provide only stdcall versions.  The third provides both, but for their stdcall version they do not and will not provide a LIB file (wyday.com).  If I could (but I can't), I would eliminate wyday.com from the picture.

I need to call routines in the vendor DLL's from both VBA directly, and from my own c++ and fortran DLL's.


From the looks of it, for the wyday stuff:

  • your Fortran (or C++) code can act like VBA, and call the VBA compatible third party "stdcall" DLL just like VBA code from Excel does using runtime dynamic linking (this presumes that the interface from Excel-VBA to the vendor DLL doesn't require a binary XLL add-in or whatever to be loaded into Excel - they don't mention this, but you'd need to check); or
  • you could write thin stdcall shims that sit within a Fortran (or C++) DLL that your VBA code calls, that then forward onto the not-stdcall variant of the third party DLL (you would no longer call the third party DLL directly from VBA - which contrary to the requirement you list above).

Mixing calling conventions in the one thing (different conventions for different API sets) isn't a drama, you just need to make sure that each caller and callee pair always agree on the convention in use. 

(From reading the vendors' website, they may be a little confused about the lack-of-meaning of stdcall on x64 windows.)

0 Kudos
Highlighted
Valued Contributor III
54 Views

It seems not so difficult, expanding on Ian comments: In your install structure you can have a 32bit and 64bit dll sub-folders.  So for your wyday dll set up a module with call interfaces and procedure pointers . Then you at run time do an init routine that uses loadlibrary with your install path to get the dll you want and use getprocaddress to get the address of the routine in the dll and associate it with the procedure pointers.  Have another routine to unload the dll and tidy up when done. Job done. Don't mess with calling standards on compile options just specify the correct call settings in the interfaces that matches the dll. 

0 Kudos
Highlighted
New Contributor I
42 Views

Thanks to all for the replies and suggestions.

I see a way to eliminate the need to call vendor routines directly from Fortran, and do it only from c++.

I will try to write a c++ DLL devoted to calling all third party DLL's.  It will necessarily use stdcall for two vendors, and cdecl for wyday.  For each, I have corresponding DLL & LIB files in win32 and x64.  My c++ code will export just one function, for calling from fortran and c.  I currently don't know how to do this

wyday's justification for not supplying a stdcall LIB file is that stdcall is antiquated.

I still need to call vendor routines from Excel VBA, but I know I can make that work by renaming vendor DLL's if need be.

I have not used LoadLibrary in Fortran, but I have used it from VBA to work around a new problem where on some end user systems Excel fails to load DLL's dynamically the same way it has ever since Excel 95.

0 Kudos