What is the need for dllimport? - visual-c++

I am playing with DLLs to get a better understanding of them. So I created a simple dll (with load-time dynamic linking) which has functions to Add, Sub and Mul. In the header file for the dll I used __declspec(dllexport) for the function declaration.
For the executable, I added the .lib created after compiling the dll to the properties (for linking). After that I directly called the function Add without using __declspec(dllimport). The program worked. I then changed the function calling to __declspec(dllimport) (Add) and the program worked again.
I am not able to understand what the need of __declspec(dllimport) is? I have not yet coded a run-time linking DLL but from the examples I have seen, dllimport is not needed in that case as well.
Thanks for your assistance.

Related

Difference between dllexport vs dllimport

I've searched through some Microsoft tutorials and all related stackoverflow threads to find the right answer. None of them is clear enough for me.
This thread still leaves some doubt.
"__declspec( dllexport ) - The class or function so tagged will be exported from the DLL it is built in"
vs.
"__declspec( dllimport ) - The class or function so tagged will be imported from a DLL"
Well, it hardly makes sense, because what does it mean "import from DLL" and "export from DLL". You can either export from and import to something, or import from and export to something.
My understanding is:
dllexport is used to specify that I want to load this code to the DLL I'm creating, whereas dllimport is used to tell the compiler that I'd like to make use of code from a DLL.
Is that correct?
When you want to use something from a dll, you include the good .h file, which will contain __declspec( dllimport ) ( often done with a #define macro for switching accordingly between export and import when we are compiling).
As a consequence you will import FROM the dll which provides this .h file.
On the contrary when you compile this dll, the .h file contains __declspec( dllexport ), telling the compiler/linker to do the job for exporting such part FROM our dll.
Have you read those:
Exporting from a DLL Using __declspec(dllexport)
Importing into an Application Using __declspec(dllimport)

Stopping dllexport functions in .lib from getting exported from a DLL

I've got a copy of the axtls library that I've compiled into a static library. I'm linking it into a DLL that I'm building, and some of the axtls functions (_MD5_Final, _MD5_Init and _MD5_Update) seem to be getting exported from my DLL. I'm trying to figure out how to stop that from happening.
My DLL is built with a .def file that doesn't list any of these functions. However, they are all declared as __declspec(dllexport) in axtls itself so I suspect that is why they're being exported.
I was wondering if there was a way to block export of these functions, using a .def file or similar? My DLL is going to be used as part of a public SDK, so it's not particularly good to be exposing internal functions like this.
I suspect removing the __declspec(dllexport) from the definitions in axtls might solve my problem, but I'd rather not go modifying upstream code if I can avoid it.
Whenever you have a static LIB file and see all it's exported functions in a DLL that uses this LIB file to build, the solution is simple:
Recompile the static LIB project without __declspec(dllexport) and then recompile the DLL project.
With a DEF file you cannot do that.

MSVC: __declspec(dllexport) does not symbols

I have a small issue when it comes to writing a DLL in MSVC (the 2010 version in particular).
My program consists of the main part and a DLL. The DLL contains a function that is
__declspec(dllexport) int test_function(void) {
return 42;
}
The file is compiled using a DLL project (not using pre-compiled headers, I have chosen a empty DLL project). Now, when I want to list the exported symbols using the dumpbin tool, the test_function is not listed under exports. Is there a specific setting that forces __declspec(dllexport) to actually export symbols?
Any help is welcome. Thank you!
That should do it. If this is the whole code, check the following:
1) You are actually checking the correct dll. Look at the timestamp. Double-check the location and the name.
2) You are compiling the specified cpp (I take it your definition is in the cpp file). Just because the file is in the directory doesn't mean it gets compiled, make sure it is added to the project.
3) Make sure your function is not excluded from the compilation unit by preprocessor directives.
Also look for other symbols and try to see what differences are there between the symbols that get exported and your function.
If this fails, you should move __declspec(dllexport) to your .h file and the definition (without __declspec(dllexport) ) to your .cpp. It might not be exported because the compiler might try to optimize it out by inlining it.

.h, .dll and .lib confusion

I'm new to vc++. I've just built a software and it generated a .dll and a .lib. I need to use functions from this in my code. Do I need to link to both .lib and .dll to build my code? What project properties do I have to alter to do this linking?
Actually, you need only the .dll file. It contains all the necessary code and data to run it's functions. It also contains a table that links the symbolic names of the functions (e.g. the function PrintMe), their ordinals (the number of that function in the DLL) and their addresses in the DLL.
If you want to use only the DLL, you have to "manually" get the symbols resolved:
Let's say you want to use the function PrintMe of the DLL. What you had to do is to resolve it's name (PrintMe) or it's ordinal (PrintMe is the 1st function of the DLL) to it's address. For this, you could use LoadLibrary, GetModuleHandle and GetProcAdress from the Win32 API (aka Windows SDK). Additionally, this method allows you to load the DLL at runtime (see below).
The easier way is to use the MSVC(++) features __declspec(dllexport) and __declspec(dllimport), e.g.
// your DLL
__declspec(dllexport) void PrintMe()
{
printf("Hello World!");
}
// you project to use the DLL
__declspec(dllimport) void PrintMe();
The first one (dllexport) tells the compiler to export the function. The second one (dllimport) is the interesting one: It creates all the necessary code to be able to use the function from the DLL.
For this, you need the .lib file in your project (which wants to use the DLL). The .lib file contains information for the linker to resolve the symbol name (PrintMe) to its address in the DLL. Since the .lib is statically bound, the linker can make use of it - the DLL on the contrary is bound at runtime / loading time, so the linker cannot use it. (Yes, the information in the .lib file is redundant.). Note: You cannot change the whole DLL when using this method w/o rebuilding your project with the new .lib file. Some structure changes affect the addresses of the functions in the DLL, see this SO answer.
One last difference between using the Win32 API (LoadLibrary...) and the MSVC method via __declspec is the loading of the DLL. When you use LoadLibrary, the DLL is loaded at runtime, of course (so you can catch exceptions when it cannot be found and so on). The other method loads the DLL at loading time, so you program will terminate (will not run) when Windows cannot find the DLL.
When you create a project in VS, you can activate the "export symbols" checkbox at the end of a wizard (Win32 project). That gives you some examples of exported symbols. Additionally, it introduces a macro plus a preprocessor defition plus some directives that are very useful:
// DLL header
#ifdef _YOUR_DLL_EXPORTS
#define YOUR_DLL_API __declspec(dllexport)
#else
#define YOUR_DLL_API __declspec(dllimport)
#endif
YOUR_DLL_API PrintMe();
You now can use this header file to build you DLL as your DLL project has that _YOUR_DLL_EXPORTS definition (see project properties page, C++, preprocessor). The project that uses the DLL can use this header, too, but then must not have such a name defined. When you include the header file in the project in which you want to use the DLL, the macro is resolved to __declspec(dllimport). This instructs the linker to look for this function (which is found in the .lib file) and create all the necessary code to load the DLL at runtime and resolve the symbol name.

What is the difference between dllexport and dllimport?

I'm just looking for a simple, concise explanation of the difference between these two. MSDN doesn't go into a hell of a lot of detail here.
__declspec( dllexport ) - The class or function so tagged will be exported from the DLL it is built in. If you're building a DLL and you want an API, you'll need to use this or a separate .DEF file that defines the exports (MSDN). This is handy because it keeps the definition in one place, but the .DEF file provides more options.
__declspec( dllimport ) - The class or function so tagged will be imported from a DLL. This is not actually required - you need an import library anyway to make the linker happy. But when properly marked with dllimport, the compiler and linker have enough information to optimize the call; without it, you get normal static linking to a stub function in the import library, which adds unnecessary indirection. ONT1 ONT2
__declspec(dllexport) tells the linker that you want this object to be made available for other DLL's to import. It is used when creating a DLL that others can link to.
__declspec(dllimport) imports the implementation from a DLL so your application can use it.
I'm only a novice C/C++ developer, so perhaps someone's got a better explanation than I.
Two different use cases:
1) You are defining a class implementation within a dll. You want another program to use the class. Here you use dllexport as you are creating a class that you wish the dll to expose.
2) You are using a function provided by a dll. You include a header supplied with the dll. Here the header uses dllimport to bring in the implementation to be used by the current program.
Often the same header file is used in both cases and a macro defined. The build configuration defines the macro to be import or export depending which it needs.
Dllexport is used to mark a function as exported. You implement the function in your DLL and export it so it becomes available to anyone using your DLL.
Dllimport is the opposite: it marks a function as being imported from a DLL. In this case you only declare the function's signature and link your code with the library.

Resources