Visual Studio Macro - visual-studio-2010

I am getting LNK2001 errors when trying to use Crypto++. The official advice for this is:
There are two ways you can deal with this, either change Crypto++ to export those classes, by using the CRYPTOPP_DLL macro, or link with both the DLL export library and a static library that contains the non-DLL classes and functions. The latter can be built by using the "DLL-Import" configuration of the cryptlib project.
It would be preferable to use the first option, and given that I am not experienced in using Visual Studio, I cannot find the location and execution method of the macro.
In short: Where do I find the macro and how do I execute it?
Cheers.

In short: Where do I find the macro and how do I execute it?
The macro is CRYPTOPP_IMPORTS. You use it when performing dynamic linking on Windows (i.e., the Crypto++ DLL).
You can 'execute' it in one of two ways. First, you can add #include <cryptopp/dll.h> to your stdafx.h. dll.h. defines it, and dll.h must be included before any other Crypto++ defines. Second, add it to your project's preprocessor macros. In either case, CRYPTOPP_IMPORTS will be defined.
I suspect you have a different error, though. You're probably not including the Crypto++ library (for static linking) or Crypto++ import lib (for dynamic linking) in your project.

Related

Do you need dllexport macro for every single function in your library in visual studio?

I am new to Visual Studio, so if I say something wrong, please point me to the right direction.
I have a large C++ project that consists of shared library of around 20 classes and 7 executables, built by CMake in Linux. Each executable has its own CMake setup that links against the library.
I watched couple of videos on VS, managed to understand how to structure code and dependent libraries and successfully compiled the library statically.
I even managed to setup CMake in Visual studio, but started receiving an error that my .dll file is not Win32 application when I tried to build a project that links to it, so I dropped CMake and built the library by first making empty project and then adding necessary files (I thought it's CMake issue).
Long story short, now I have new setup for my library in VS that builds without issues. However I want my library to be dynamic because it makes ton of sense as 7 different projects depend on it and that's how I did it in Linux.
To my big surprise, even though selecting .dll will build, it cannot be linked to (I started all of this as empty project, not .dll template).
What I just discovered that building .dll library requires a macro that looks like (taken from https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170):
#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif
and before return type of any function in library I need to add the macro as:
MATHLIBRARY_API double some_function();
So if I understand correctly, this macro is "exporting" function names to .dll. Does that then mean that I need to open all 20 header files and wrap every single function in it with the macro?
Note that most header files are class declarations, do I need to wrap every single class method, just the public methods and is there a way to make a whole class "exported"?
It seems quite a cumbersome task just to build a shared library. I realize now this is why cmake failed and kinda begs the question on its cross platform capabilities if this wrapping to make .dll in VS needs to be done like this.
I am considering building my library statically, and in the same solution, add additional projects, and make a reference to the static library.
It kills modularity of the project, but it should work fine.

Many functions in pocketsphinx (like bin_mdef_free) not exported to lib on Windows

I am writing an simple phoneme forced alignment demo. I just copied some initialization code in the unit test file.
However, there are some functions causing LNK2019 error. Here is the list:
bin_mdef_free
dict_init
dict_free
dict2pid_build
dict2pid_free
ps_alignment_init
ps_alignment_free
I manually listed the symbols in pocketsphinx.lib, and I found many bin_mdef functions are listed, but except bin_mdef_free. (using DUMPBIN /ALL) All alignment functions are missed.
What should I do to include them in my lib file?
This is just because pocketsphinx did not export these functions. One should add POCKETSPHINX_EXPORT macro to these functions and recompile the source code to lib file.

Including C++ header files in Objective-C++ when they conflict with Objective-C macros

In Xcode, I've created a "Cocoa application" project. One of its dependencies is a framework containing C++ code. I renamed AppDelegate.m to AppDelegate.mm and included the framework.
The project fails to compile. The problem is that the C++ header files in the framework are using some symbols that conflict with Objective-C or Cocoa.
The C++ header files are defining functions called verify() and check(), which conflict with /usr/include/AssertMacros.h in the MacOSX10.8 SDK.
The C++ header files contain a variable called NO, which conflicts with the Objective-C macro NO.
A workaround would be to modify the C++ code in the framework to avoid these conflicts. But since it's a large C++ project maintained by another organization, this would take time and would possibly break in future updates of the C++ project.
Is there some way just to tell Clang/Xcode to treat those C++ header files as C++ instead of Objective-C++?
Reading through the /usr/include/AssertMacros.h that comes with Mac OS 10.8, it looks like you could do:
#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
before including AssertMacros.h, which will prevent it from defining macros called verify() and check().
Regarding NO: you could use the preprocessor to rename that variable for you. For example:
#define NO NO_libraryname_renamed
#include <libraryname.hh>
#undef NO
Depending on how the NO variable is used by the library, this might cause problems — if the header is declaring it as extern, then your Cocoa app will refer to it by the wrong name, and you'll get an undefined symbol error. But as long as you're not using that variable, and the library isn't depending on your app to define that variable, then you should be fine.
(And please file a bug report with the offending library, requesting that they rename their variable.)
Mixing several languages is calling for grief. Even more so mixing Objective C++ (itself a strange hybrid) with C++. Don't do it.

Cmake add_library with boost source files introduces references to non-existant files

we're building a cross-platform utility which must have a small footprint. We've been pulling header files from boost as and when we need them but now we must link against some boost C++ thread code. The easiest immediate solution was to create our own custom library using CMake's "add_library" command to create a static library composed of some boost thread source files. These compile without any problems.
The difficulty arises when I try to link to this library from an executable. Visual Studio 2008 returns an error saying that it cannot link to "libboost_thread-vc90-mt-sgd-1_40.lib". What really puzzles me is that I've grepped through all the source code and CMake config files and I can't find any reference to this libboost library, leading me to think that this has been autogenerated in some way.
This works OK in Linux, can anyone point out why I'm experiencing these issues in Windows?
#Gearoid
You found the correct reason for your problem, but not the correct solution. The BOOST_AUTO_LINK_NOMANGLE is an internal, i.e. for library authors, definition to control the auto-linking. The user level definition is BOOST_ALL_NO_LIB which when defined disables the auto-linking feature for all Boost Libraries code you use. This is described in the user.hpp configuration header (see user.hpp near the bottom and the Boost Config documentation). You can also control this on a per library level as describe in that header.
Ok, well, it turns out that Boost uses this auto-link feature for Visual Studio which embeds references to a mangled (ie, platform-compiler-mult-threaded, etc) boost library name.
The header file which controls this is called "auto_link.hpp" which lives in the config directory of the boost include tree. There's a special preprocessor definition called "BOOST_AUTO_LINK_NOMANGLE" which toggles this behaviour.
Another triumph of mediocrity for Microsoft.

How do I compile boost using __cdecl calling convention?

I have a project compiled using __cdecl calling convention (msvc2010) and I compiled boost using the same compiler using the default settings.
The project linked with boost but I at runtime I got an assert message like this:
File: ...\boost\boost\program_options\detail\parsers.hpp
Line: 79
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
There are the following questions:
what calling convention does boost build with by default on Windows (msvc2010)
how to I compile boost with __cdecl calling convention
why boost wasn't able to prevent linking with code with different calling conventions? I understood that boost has really smart library auto-inclusion code.
Update #1
It looks that boost does compile and link with proper calling convention, still at runtime I get the above problem. I did a sample application using the same code and it works but in my application it fails. The only difference could be from project configuration or includes/stdafx.h
Just use
bjam ... **cxxflags=/Zp4**
while building boost libraries.
As far as I know there's not way to make C++ use cdecl calling conventions (see MSDN Calling Convention). The C++ method calling is just different from C. The only opportunity that you have to use one of the C calling conventions is for functions, which include class static functions in C++. If you know that's the case you can try forcing the option when building by adding the option during the build:
bjam cxxflags=/Gd ...
(see BBv2 Builtin features)
Or to make it "permanent" set up a user-config.jam with your compiler and add it to the build options for all BBv2 msvc builds (see BBv2 Configuration and related docs). As for you other questions:
Boost uses the default calling convention MSVC uses, except for cases where it overrides it at the code level. I don't know where those are as they are library specific. So you'd have to search the code for the "__*" code decorators.
See above for partial answer.
Detection; there are two reasons: There is a limit to how many different options we can reasonably detect for for building as it's an exponential growth of different possible variations so we limit it to the most important cases. And in the case of calling convention, it's not actually possible since it's something that can be changed on a per function basis.
I found the cause of the problem inside one of the shared property files: <StructMemberAlignment>4Bytes</StructMemberAlignment>
If I remove it the code will work. Still, I'm not sure why this is happening and how could I solve it without removing the above code (that was required by another library).
I added another question regarding boost and structure member alignment.

Resources