Forbid linking against a c++ method - c++

I try to forbid the use of a method, to have a compile error if some piece of code use it.
This is a proprietary legacy module, that I know that some methods are problematic. We have headers files, and dlls.
I can't figure out all the use of this method in the huge project I use (lot of defines, some implicit cast...)
Can the compiler stop (or just warn) if it detect the use of this method?

You can use __declspec(deprecated) in Visual C++ to generate warnings for use of a specific function. You can use #pragma deprecated to deprecate the usage of any symbol (including macros).
See more information on MSDN. This can generate warnings or errors (depending on computer flags) but you can supress them where needed with additional #pragmas

Well, not sure if it works or not (so please correct me), but you might want to play with making libs out of your DLLs
something along the line, from VS command prompt:
dumpbin /exports yourdll.dll
you'll get export symbols output and copy it into .def file
edit .def file to remove unwanted symbols
make lib and link it to your app
lib /def:C:\mydef.def /OUT:C:\mylib.lib

Related

Visual Studio "object file does not define any previously undefined symbols"

While using C++ in Visual Studio 2013, I've come across a really weird warning/bug thing.
I have a static library and a console application.
Static library imports 4 3rd party .lib files, and their headers.
Console application imports the static library and the headers of the original 4 .lib files, so that I can use the code from the original 4 .libs and my .lib.
(I think this is the right setup in this situation, if there is a better way, do tell!)
However, when I build the static library, I get a warning: "LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library" for each .lib imported.
But where is it getting the code if not from the libraries? If I remove the .libs from being imported, the build fails stating that it needs them! I don't know what to do in a situation like this. I would be happy enough to just leave the .libs being imported as is and ignore the warnings, but when I try to disable them (Under disable specific warning, "4221", in the compiler options), the warnings are not disabled!
Edit: The 4 3rd party .libs are standalone - they do not use each other's code so I do need to import all of them.
I am truly at a loss - any advice would be much appreciated.
I found a way of disabling the warnings using /ignore: on the linker command line, but I'm still confused as to why the linker gave the warnings in the first place, when removing the library as input caused multiple "unresolved external symbol" errors.
Oh well, problem (sorta) solved.

How do i make dll smaller with MSVC++ 2010?

i have some huge c++ projects, all of then are compiled with msvc++ 2010.
i want the DLL file to be smaller,
can anyone give me some inspiration?
Compile for release, use Link Time Code Generation (LTCG), remove unused references (OPT:ICF), put the CRT in a DLL. Don't export things from the DLL unless necessary.
In addition to the other answers, you can use upx to compress the dll, or some other compressor.
http://upx.sourceforge.net/
In addition to the above suggestions, Make sure in Project Properties->C/C++->Favor Size Or Speed, Favor small code (/Os) is selected.
Compile as release, not debug.
Link with MSVCRT dynamically instead of statically. This means you likely have to distribute the MSVCRT DLL with your program. Depending on how your program is structured, changing the links of CRT can have unintended side effects.
Remove all the code that isn't needed. Use a profiling or code coverage tool to identify code that doesn't appear to be getting called. You might be able to remove it.
Look at all the corresponding .obj files for each .c or .cpp file. If any one obj file is excessively large relative to the size of the code file, that might be a hint something could be reduced there.
Minimize the use of global instances or global data in your DLL. The binary size will bloat by the number of bytes of global variables declared.
Only export the very minimal number of functions you need to have other EXEs and DLLs import. Run "dumpbin /exports yourfile.dll" to get the list of exported functions. Only export functions that are directly called by the code relying on the DLL. If you are exporting something that no one outside of the DLL is going to call directly, don't export it. The linker will optimize it (and it's dependents) from being used if nothing internal is calling it.
Don't export entire C++ classes. Export simple C wrapper functions if your DLL is C++ code.

Suppress import library creation - Visual C++ linker

Is there, a perhaps undocumented way to prevent linker from creating IMPLIB for a DLL or an EXE, despite having __declspec(dllexport) directives within the source code?
Specifying no /IMPLIB results in .LIB created with a default name.
This is important when the declspec directives arrive from 3rd party code which is not under control. This is, for example, the case with boost::serialization. A possible solution would be a way to "undeclare" a DLL export. DEF file also cannot do it (AFAIK), because it can only add to the export list but not remove from it.
Many 3rd party code does not use __declspec(dllexport) directly, but hides it under a macro in order to control it. Typically they want to switch between dllexport and dllimport depending on where the header file is included (inside the dll implementation or by the user of the dll)
If that is the case in the library you try to include it should not be too difficult to alter this behavior via macro manipulation to meet your exact needs.
For example, boost::serialization check the config.hpp and see how you can control it.
According to this, if you supply the .exp file when linking, the linker will not create a .lib file. To be honest, though, I can't tell if this helps in your case.
There is not any way to do this with a linker option, using /implib:"nul" fails miserably when the linker uses it to name the .exp file. The most practical solution is to remove the files again after a build. Project + Properties, Build Events, Post-Build event and paste:
del $(TargetDir)$(TargetName).lib
del $(TargetDir)$(TargetName).exp
Using a .def file containing your exported functions marked with the PRIVATE keyword will tell the linker to skip placing the symbol in your import library.
Refer to this MSDN page for more information about MSVC's .def file syntax.
Nowadays, you can use /NOIMPLIB and /NOEXP in the advanced linker options as per this bug ticket. Works for me on Visual Studio 2019.

how to automatically export names in C++ source to be used in DLL

I have a library, written in C++ (and I have its full source). Due to its LGPL license I can only use it with the proprietary software of my company via dynamic linkage (static linkage works fine). So, I need to build it into a DLL. However, the library is quite big and doesn't export anything (hence no .def file and no __declspec(dllexport) statatements in front of the class and global function names). So, when I build a dll, it's useless, as it doesn't have exported names, so it won't link.
In our company we are using MS Visual C++, which by default does
not export names (while, for instance, GNU GCC, when run via MINGW on Windows does). So, the only option I see at the moment is placing __declspec(dllexport) in front of every name in the library that I'm using (and there are thousands), or writing a .def file for those names. But even if I did that, I will not be able to use the next version of the library,
as I'll have to do this job again. I was looking for a tool that does these exports, or generates a .map file, but none really do this specific task
(there are some DEF generators, but they mostly search the result of DUMPBIN /EXPORT which gives nothing in my case). I was searching the web for answers for two days now, but no good result.
Best regards,
Andriy
IANAL But if the library is LPGL they should be open to dynamic linking.
Have you considered modifying the source file and updating Makefile to give a way to generate the dynamic library and getting it approved by the maintainer ? Chances are they will be open to it and future versions will just work.
I don't think that there is such a automation you want.
My suggestion is editing the source code (as you said); using Notepad++'s macros or using Replace Pioneer
Regards

How to link to VS2008 generated .libs from g++

I am trying to build a dll using mingw g++ under cygwin.
I have .h files that refer to objects exported by a .dll that was build using MS Visual Studio 2008. I link to the .lib generated with that .dll.
When I run g++ I get lots of errors like this
/cygdrive/c/dev/blox/ulfx/ulfx/JavaInterface.cpp:206: undefined reference to `__imp___ZNK18DLLSafeDoubleArray4sizeEv'
The .dll that I want to link to exposes a function named
?size#DLLSafeDoubleArray##QBEIXZ
And I assume that the problem here is that the g++ name mangling is incompatible with the VS2008 name mangling.
Is there a way I can force g++ to use a compatible mangling ?
I do not have any version of Visual Studio installed on my machine.
G'day,
Not sure if this is going to be possible as there is too much that can vary between compilers from different vendors apart from just the name mangling. Things such as:
this handling,
layout and contents of v-tables,
class layout,
parameter sequence,
register handling,
return value handling,
etc.
I'd be interested to see if it was possible though.
Maybe this page helps:
http://www.mingw.org/wiki/MSVC_and_MinGW_DLLs
I did manage to do something once but it was just a prototype which I abandoned when I found a library doing what I wanted. I did follow their instructions though, but I was producing the dll myself.
I agree with Rob Wells comment, there are a lot of things in C++ that may break.
Something which should be easier, safer, and possible would be to use plain C functions, as the main thing to worry about there is the calling convention and potentially packing and alignment of structs.
Object code produced by different C++ compilers is not link compatible.
This is done on purpose: compilers use different ABI, and if the name maingling didn't prevent you from linking, you'd now be wondering/debugging why the simplest operations are causing your executable to crash.
You should be grateful that the different name mangling scheme spared you that debugging effort.
Better way is to recompile dll with g++. If it is possible.