C++ - Class definition with syntax using DLL - c++

What does it mean exactly when I define a class this way in C++ project:
class THIS_DLL_NAME class_name{
...
}
thanks!

As Basile and Hans stated in the comments above, THIS_DLL_NAME will be a macro that conditionally expands depending on whether you are building the library itself, or code that just uses that library.
(BTW, I'm assuming you're on Windows here, due to the DLL terminology.)
THIS_DLL_NAME can expand to either __declspec(dllexport) or __declspec(dllimport). When the header file is included in the .cpp files that you're compiling into THIS_DLL.dll, the compiler needs to see __declspec(dllexport) in order to generate the proper entry points to export them from the DLL.
When your class header is included in code that is using THIS_DLL.dll, the compiler needs to see __declspec(dllimport) in order to generate the right code to import the symbol (and resolve it at runtime).
You can read up on more of the details straight from Microsoft in this article - Importing and Exporting (MSDN).

Related

How to use a provided DLL file with HPP header?

I’m currently having some problems trying to implement an integration with a Verifone PoS.
The bank we are working with provided us with one .dll file, one .h file and one .hpp file.
I’m usually a Java or PHP developer, so for the last days I consumed everything I found on the web about DLL files and how to use them, but none seemed to work so far. I got a lot of errors, many of them being something like “invalid dll”.
I found on the web that alongside a dll file there should have been a .lib file. I asked the third party about this, but apparently
There is no .lib file. The .dll file contains all the required info for an integration
From their documentation of library I found this:
The form of the supplied binary is a dynamic library. By its nature, a dynamic library allows for easier updates and corrections, not requiring recompilation or relinking of the client (calling) code, as long as the procedures prototypes (function parameters and return types) remain the same.
The language used for the library implementation is C++.
To access the functionalities implemented in the library binary, a C-style header interface is provided. This is comprised of the function prototypes available to be called as well as the types of the result-structures through which the returned data needs to be interpreted to make sense for the previously accessed functionality (the specific requested transaction).
So yeah, the .h file includes only the data types, and the .hpp file contains some declarations that looks like this:
extern "C" __declspec(dllexport) bool doSomething(int param);
Also in their documentation there is an example of how an implemetation should look (and it is fairly simple):
bool someVar = doSomething(1);
It looks like those functions can be called as simple as that, but they cannot. If I try to do that I get an “undefined function” (or similar) error.
At this point the only thing that seemed to have somehow worked (maybe) is loading the DLL with the LoadLibrary function. But besides the fact that whatever function I try to call, with whatever parameters, it returns false, it seems kind of wrong that I do not use the .hpp file at all.
So here we are. How I should aproach this? Is there a way to load the DLL and use the provided HPP file as function definitions? If not, is there another way beside LoadLibrary + GetProcAddress combo to do this?
Thank you!
I'm assuming the dll is a native dll, not a managed assembly (.net dll).
Usually, the dll author adds a preprocessor definition to the build system, like DLL_EXPORT. So if the author compiles the dll, the import library (a small .lib file) will contain all functions that used the DLL_API macro. Then the author can ship the very same header to a user. Because that user won't have the DLL_EXPORT macro defined, DLL_API will resolve to a dllimport, which basically says that the annotated function is defined in the import library.
Such a header might look like this (the whole #if condition is usually in its own header file which is then included in all headers that export functions):
#ifdef DLL_EXPORT
# define DLL_API __declspec(dllexport)
#else
# define DLL_API __declspec(dllimport)
#endif
extern "C"
{
void DLL_API SomeFunction(int x);
void DLL_API AnotherFunction(int x);
}
If the author builds the project (in msvc) the compiler will generate the dll file and a small .lib file, which is the import library. This lib will essentially do what you have to do now: calling LoadLibrary and GetProcAddress to resolve all the functions that have been annotated with __declspec(dllexport).
The following part is a bit speculative and I'm guessing a bit here.
All __declspec(dllimport) does, is tell consumers that this dll contains those functions. But the linker has to link a declaration to its definition (implementation) so the function must be defined somewhere at compiletime. And that place is the import library (.lib). If you don't link with the import library, you will get a linker error when you build your project.
This means simply changing the dllexport to a dllimport won't solve your problems. Without an import library your only option is to load the dll manually with LoadLibrary and search for each function.
If I were you, I'd ask the author for an example project that uses the dll. AFAIK, the only ways to use a native dll is either by linking to an import library or by loading everything manually.
Manually generating the import library from the dll
I've tested this to make sure it works.
First of all, fix the header file to either use the macros like I did in the example above, or just use dllimport directly.
Second, open the developer command prompt for VS and follow the steps from this answer. Make sure to use the correct file names and target architecture (x64 or x86). Now you should have a .lib file.
Thrid, add the lib to your project.
Add the directory of the lib (place it somewhere close to the project so you can use relative paths). Open the project properties and follow the steps in this image:
Make sure that Configuration and Platform are correct (you probably want it like in the image). You can also use relative paths. Click on the Macros button to see all predefined paths available to you.
Add the lib to the linker dependencies:
Put the header somewhere in your project where you can access it.
Now you can simply include the header anywhere in your project and use the functions declared inside it. But note that the dll file has to be placed somewhere where LoadLibrary can find it. Preferably this is the same directory where your project's executable is located.
Bonus facts
The definition file (.def) is actually very simple. The def file for my sample code above is:
LIBRARY MyLibrary
EXPORTS
AnotherFunction
SomeFunction
If I remove the extern "C" block around my declarations, my function names will be mangled and the def file looks like this:
LIBRARY MyLibrary
EXPORTS
?AnotherFunction##YAXH#Z
?SomeFunction##YAXH#Z
If you put those functions inside a namespace (for example FooSpace), that namespace name will also be part of the function name:
LIBRARY MyLibrary
EXPORTS
?AnotherFunction#FooSpace##YAXH#Z
?SomeFunction#FooSpace##YAXH#Z
Note that all extern "C" entities will ignore namespaces, meaning all extern "C" functions, variables, types, ... will be put into the global namespace, no matter if you define them inside a namespace or not.
These are also the names that you'd have to pass to GetProcAddress if you did it manually.

Compiler C2491 error: solution requires loss of data? [duplicate]

I am working on a C++ (VS2017) project that uses a protobuf type I created.
However, this project requires a .dll of said protobuf type. The __declspec( dllexport ) in each class declaration are not there by default, and I read online that they can be added by generating the protobuf object with this command line:
--cpp_out=dllexport_decl=MY_EXPORT_MACRO:output/directory
No one has explained what MY_EXPORT_MACRO is or how to define it. When I first generated my protobuf objects I used the most basic line and it worked:
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/my_file.proto
What and where is MY_EXPORT_MACRO and/or is there another way to make my protobuf files .dll compatible?
You know about __declspec( dllimport ) also, correct? What's the easiest way to use the same type definition while building the DLL (with dllexport annotations) and in DLL clients (with dllimport annotations)?
Having a macro to switch the annotation is an extremely common practice in Win32 DLL development of all sorts, not just for protobuf DLLs.
Usually the definition runs like this:
#if BUILD_DLLX
# define DLLX_API __declspec(dllexport)
#else
# pragma comment('lib', 'dllx.lib')
# define DLLX_API __declspec(dllimport)
#endif
And then you would use --cpp_out=dllexport_decl=DLLX_API:$DST_DIR so that the generated header files have DLLX_API inserted in the right places. Then build the DLL with /DBUILD_DLLX so it exports the types and functions.
Consumers of the DLL can #include the exact same header file, and with no /DBUILD_DLLX in their project configuration, they'll end up with imports.

macro in function declaration

I'm looking at the v4l header files and I found function definitions with the following structure.
#define SOME_VAR
SOME_VAR int somefunc(int i,....);
What is the purpose of using the #define directive in such a way?
Thanks in advance
You can specify a calling convention or a import/export tag. For example Visual Studio you build a DLL and have some functions to export, you can reuse your header file. For compiling the export you use
#define SOME_VAR __declspec(dllexport)
on the import site you write
#define SOME_VAR __declspec(dllimport)
using only one include in both situations reduce the possible errors during updating and bug fixing of the code.
In the case you mentioned above it seems to be for future use as some platforms have other calling conventions (e.g. the pascal calling convention) than others.
Visual Studio uses a similar stub, the macro WINAPI, which is also empty.

How do I fix an Unresolved External Symbol error in my C++ DLL?

I have a dll, which accesses some classes outside of its project (I'm using Visual Studio, so I have two projects). The thing is, in the header that the dll includes, which is outside of the dll's project, there are only bodies of functions, like this:
x.h
class x
{
void myFunc();
}
And in another cpp file, outside of the dll file:
#include "x.h"
x::myFunc()
{
//.....
}
The dll is only getting the bodies of the functions, so when I compile, I get lots of unresolved external symbols (I'm quite sure that this is the issue, because I tested with another class fully built in a .h file, in another project, and no errors). So how can I solve this mystery?
It is normal for the import headers to only have function signatures; the actual function bodies are already compiled into the DLL binary and are resolved at link time by linking into the actual DLL.
The first thing to try is to make sure you are actually linking to the said DLL. It isn't enough to just include the header, you also need to link to the binary. So in your project configuration, you need to add a link to (for example) the .lib file that gets created along-side the DLL when the DLL is compiled (if in MSVC). This lib file lets the linker know how to connect the function signatures you included via the import header to the actual implementations contained in the DLL. If you're on a different platform, the mechanics might be a little different, but the concepts will be similar.
Edits:
The next step is to make sure the binary is actually exporting the symbols you're trying to link against. Make sure that all interface signatures are being exported via __declspec(dll_export) prefixes. Normally this is wrapped up in an IFDEF so that the header is declared export while the DLL is being compiled, but not when that header is included in a client project. Next, you could use dumpbin to check the mangled export names, and see if there is anything unexpected.
Here's a modified version of your example that illustrates this style of export (note, I haven't tested if this compiles, apologies for any typos):
#ifdef BUILDING_MYDLL
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
class MYDLL_API x
{
void myFunc();
}
You would then set your configuration to define BUILDING_MYDLL when compiling the dll, but not when compiling the executable. This way the functions are only marked export when compiling the library dll. Now you can mark your public API functions with MYDLL_API and they should get exported during build.
Please note that dll_export, dll_import, and declspec are all very MSVC-specific constructs. Other compilers/runtimes handle symbol export in different ways.
There's multiple ways to link DLL into your app on Windows, check out this existing question/answer:
https://stackoverflow.com/a/2060508/1701823

How to block a function from being exported in MS VS C++?

So for the sake of the argument, I have a module called ExportedFunctions.cpp whith a couple of functions decorated with the DLL_EXPORT (see below)
#define DLL_EXPORT __declspec(dllexport)
ExportedFuncitons.cpp includes a LibraryFunctions.h. The functions declared in that header are implemented in LibraryFunctions.lib and statically linked to my project.
The problem is that when I compile my DLL and look at it using a dependency walker (depends.exe), I can see not only the functions exported by ExportedFunctions.cpp, but also all of the functions in LibraryFunctions.h.
That is the case even if I delete some function declarations from LibraryFunctions.h. They keep showing as DLL entry points. I want to hide them.
Figured it out.
The problem is that the lib file is exporting the functions. It looks like it exports regardless of what the .h file is saying.
Luckily I'm also the owner of LibraryFunctions, so I recompiled it using "Release - Static Lib". In that configuration I block the dllexport directive.