Format for DLL calls

Format for DLL calls

My applications are DLLs intended primarily to be called from Excel/VBA, and so my entry points look like:

Subroutine WaterSatDensity_F(TempC, Value, Units)

!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, ALIAS:'WaterSatDensity_F' :: WaterSatDensity_F

!DEC$ ATTRIBUTES REFERENCE :: Units

For one group of installs on a server, Excel is not installed, and so I need a simple way to check that the install is correct, my user licensing is operating and the DLL is returning valid results. I want to write a Fortran main program, which will call the DLL using the same entry points as VBA.  What should my calling program look like?  

Thanks,

David

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Do you want to load time link (Windows automatically loads the DLL and establishes the relevant links between procedure references and the procedures) when your test program loads) or run time link (you direct the loading of the DLL and the linking of procedures references to procedures using the Windows API) to your DLL?

You use runtime linking if you want to have greater control over the loading and linking process.  Otherwise load time linking is easier.

Ian,

Load time linking is fine.  However, since Excel does not know the location of the DLL (it should be on the path), I need the Fortran program to also rely on the DLL being found.

I need to know how to declare the entry points on the caller to match STDCALL, and I'm not sure how to do this (haven't needed to do it for a long time).

Thanks,

David

If load time link, add the .lib import library for your DLL to the link step for your test program (this can be done implicitly using project dependencies). 

If your DLL entry points are in a module, then in your test main program just use that module and call the entry point like you would any other procedure.  If your procedures are not in a module, copy paste the relevant chunk of the specification part (argument declarations and calling convention definitions) into an interface block in your main program, change DLLEXPORT to DLLIMPORT, and call the entry point like you would any other procedure.  Then write yourself a note promising to use modules next time and super glue it to the forehead of a nearby colleague.

 

Ian,

Creating a module is not hard, because all of the wrapper routines with the entry points are in a single file.  I guess that when they are in the module, I do not ever "USE" the module in the DLL project, because these routines aren't called by anything in the DLL.

Thanks,

David

That sounds right.  The module in this case is really just a way of conveniently packaging up the interfaces for Fortran clients.  But to be clear, the DLL entry points could also be spread across multiple modules - in which case within the DLL itself one of the modules might reference another.

David,

See this topic including Steve's suggestion - there is a simple (but complete) example that you may be able to adapt for your needs.

Cheers,

David,

Also, one of the applications I've developed is similar to yours i.e., it is a DLL that is used by various programs, but which is consumed extensively via Excel.  And for this DLL, I've found the use of definition files a lot more convenient than export/import compiler directives.  See my comment in connection with this topic.

Quote:

Steve,

Quote:

You should use

!DEC$ ATTRIBUTES DLLEXPORT :: procname

in each of the type-bound procedures, public and private, where "procname" is the name of the specific procedure. I recommend this over .DEF files

 

Thanks for your suggestion re: the use of DLLEXPORT over module-definition file. You must be surely aware of the pros and cons of these two options. For the benefit of other readers, I attach a link to Microsoft's MSDN site that explains it nicely:

Quote:

Pros and Cons of Using .DEF Files

Exporting functions in a .def file gives you control over what the export ordinals are. When you add additional exported functions to your DLL, you can assign them higher ordinal values (higher than any other exported function). When you do this, applications using implicit linking do not have to relink with the new import library that contains the new functions. This is very important, for example, if you are designing a third-party DLL for use by many applications. You can continue to enhance your DLL by adding additional functionality while at the same time ensuring that existing applications continue to work properly with the new DLL. The MFC DLLs are built using .def files.

Another advantage to using a .def file is that you can export functions using the NONAME attribute, which places only the ordinal in the exports table in the DLL. For DLLs with a large number of exported functions, using the NONAME attribute can reduce the size of the DLL file. For information about writing a module definition statement, see Rules for Module-Definition Statements. For more information about ordinal export, see Exporting Functions from a DLL by Ordinal Rather Than by Name.

The major disadvantage of using .a def file is that if you are exporting functions in a C++ file, you either have to place the decorated names in the .def file or define your exported functions with standard C linkage by using extern "C" to avoid the name decoration done by the compiler.

If you need to place the decorated names in the .def file, you can obtain them by using the DUMPBIN tool or by using the linker /MAP option. Note that the decorated names produced by the compiler are compiler specific. If you place the decorated names produced by the Visual C++ compiler into a .def file, applications that link to your DLL must also be built using the same version of Visual C++ so that the decorated names in the calling application match the exported names in the DLL's .def file.

Pros and Cons of Using __declspec(dllexport)

Using __declspec(dllexport) is convenient because you do not have to worry about maintaining a .def file and obtaining the decorated names of the exported functions. This method is suitable if, for example, you are designing a DLL for use with an application that you control. If you rebuild the DLL with new exports, you also have to rebuild the application because the decorated names for exported C++ functions might change if you recompile with a different version of the compiler.

 

My situation is more like that of a 3rd party DLL and I've been using the .DEF file approach with several libraries written in C and it has worked well.

Regards,

Leave a Comment

Please sign in to add a comment. Not a member? Join today