How do people handle warning C4793: 'some_function' : function compiled as native? - visual-studio

I'm using the OpenCV library and one of its header files, cxoperations.hpp, generates "warning C4793: 'anonymous namespace'::CV_XADD' : function compiled as native", if my C++ project is compiled with CLR support. I can prevent the warning by surrounding the OpenCV header include like this:
#pragma managed(push,off)
#include <cv.h>
#pragma managed(pop)
But the project that actually uses OpenCV isn't compiled with CLR support, it's a native C++ static library. The project that does have CLR support, and generates this warning without the pragma statements, simply uses this static library. So I'm a bit surprised that the warning was created at all, especially given the fact that the entire static library is not compiled with CLR support, and yet it's only this one header that causes the problem.
Thus this solution seems sub-optimal to me. Is this how you would handle this warning, or can you recommend a better practice?

I think what you want is this:
#pragma unmanaged
#include <cv.h>
#pragma managed
// managed code wrapping unmanaged opencv functions
A C++/CLI project can contain both managed and unmanaged parts, and the compiler takes care of marshalling data between the 2 for you. The managed entry points will be callable from normal .NET apps (like C# and the rest) and will use garbage collection, and they'll call unmanaged functions to do the heavy lifting.

I think you should suppress the warning. The MSDN doc explicitly states that the managed/unmanaged pragmas should not be used before include statements.
#pragma warning(push)
#pragma warning(disable: 4793) // methods are compiled as native (clr warning)
#include <cv.h>
#pragma warning(pop)

If you cannot change existing code files, you can get rid of the warning by disabling CLR support for the specific file that shows warning 4793. Of course, this only works if this file does not make any use of CLR features.
To disable CLR support for a specific file, locate it in Solution Explorer, right-click and open its Property Pages. Set Common Language RunTime Support to No Common Language RunTime Support. Don't forget to do this for All Configurations and All Platforms.

Related

Is Static link of DLL (using *.lib) possible from code only (without add to project, something like #pragma link "...")?

I am upgrading my preexisting CAD/CAM project (quite big one > 10MByte of code) and have to add some special measuring equipment. The problem is I have more than one supplier of the measuring system (although is already decided which one to use) and I want to configure them (using #define in case vendor is changed in future) with code to use only selected device type. So I have something like:
#define use_vendor1
//#define use_vendor2
//#define use_vendor3
and some of the vendors APIs require their own DLLs so I need for example:
Project/Add to project/vendor1.lib
Project/Remove from project/unused_vendor.lib
if use_vendor1 is used ... That will be uncomfortable to add/remove each type reconfiguration of exe is required. I was wondering if there exist a way similar to this:
#ifdef use_vendor1
#pragme link "vendor1.lib"
#endif
That one does not work of coarse because DLL *.lib is not compiled code as *.obj ...
Having all the libs in the project is an option but that would require shipping exe with all the DLL's which I would rather avoid.
Another option would be dynamic DLL link but I rather avoid it as that is more coding for me in it...
I am bound to old BDS2006 Turbo C++ Explorer IDE and compiler.
Also is it possible to statically link DLL in relative path to EXE ?
You are looking for #pragma comment:
#ifdef use_vendor1
#pragma comment(lib, "vendor1.lib")
#endif

C++/CX Header file can't find Microsoft namespace

I have a header file with the following code:
Microsoft::WRL:ComPtr<ID3D11Device2> m_device;
inside a class definition. Visual Studio 2013 is saying that Microsoft is not a namespace, if I take the code and cut it out and put it in another class in another file unchanged it works just fine!
Any ideas?
Philip
EDIT: All of a sudden (without me having changed anything) Intelissense now accepts Microsoft::WRL::ComPtry as valid but when I compile it still gives me errors that it does not exists.
You need to
#include <wrl.h>
or
#include <wrl/client.h>
To get Microsoft::WRL::ComPtr in your module.
When you say "Visual Studio 2013 is saying that Microsoft is not a namespace" do you mean you get a compiler error or is just Intellisense? When dealing with headers, Intellisense can get a bit out of sync until you build again. For example:
//Test.h
class A { Microsoft::WRL::ComPtr<T> a; };
//Test.cpp
#include <wrl/client.h>
#include "Test.h"
If you just added the #include <wrl/client.h> to the Test.cpp, Intellisense might not know yet it is in scope for the header. It's perfectly valid C++ already, but a better practice is to include in your headers the ones it needs like:
//Test.h
#pragma once
#include <wrl/client.h>
class A { Microsoft::WRL::ComPtr<T> a; };
The other way this sync issue can manifest itself is if you are doing:
//Test.h
class A { Microsoft::WRL::ComPtr<T> a; };
//Test.cpp
#include "pch.h"
#include "Test.h"
//pch.h
#include <wrl/client.h>
Again, fully valid C++ that will build. Intellisense knows it works when you build, but might not until then.
Note: WRL is traditional C++ and is not using C++/CX language extensions. They both exist to make it easier to consume WinRT APIs from C++, and you will see the Microsoft::WRL::ComPtr used inside C++/CX applications when dealing with non-WinRT COM APIs like Direct3D. And you can mix C++/CX with WRL in the same application taking advantage of the fact that you can use reinterpret_cast<> between C++/CX ref ^ and ABI COM pointers. You can use Microsoft::WRL::ComPtr in old-school Windows desktop apps on Windows 7 or Windows Vista too.
With all that said, WRL and C++/CX are two distinct things.
Update: For consuming Windows Runtime APIs, you can also use C++/WinRT which is also 'standard' C++ without any need for the C++/CX extensions. See Microsoft Docs. You can use Microsoft::WRL::ComPtr for C++/WinRT applications, or you can use their variant wrl::com_ptr

Detecting ABI compatibility issues with GCC

I recently spent a fairly substantial amount of time tracking down a problem that turned out to be caused by compiling a library with -D_GLIBCXX_DEBUG (which tells libstdc++ to use a debug version of the standard library with extra checks) but compiling the client program without. This caused an ABI compatibility problem.
Is there some way I can automatically detect problems like this with GCC? Visual Studio provides the detect_mismatch pragma which I think would have served this purpose, but I'm unaware of any GCC equivalent. GCC does something with embedding a symbol name (e.g. GLIBCXX_3.4.9), and I can imagine schemes that would cause a linking error because of an undefined symbol if a corresponding symbol (e.g. mylib_debug_stl) were not present, but the only ways I can think of to get a use of that symbol are really hacky.
Alternatively, how do other people avoid this issue? Build the checked version of the library to a different name or something like that?
Is there some way I can automatically detect problems like this with GCC?
Only the linker can detect if you link incompatible code, not the compiler.
The alternative linker, gold, can detect some problems with the --detect-odr-violations option.
Alternatively, how do other people avoid this issue? Build the checked version of the library to a different name or something like that?
I just ensure I rebuild everything when I want to use the Debug Mode, I don't think I've ever wanted to keep a library around that was built with Debug Mode. It's meant for debugging, not for normal use.
I rarely use -D_GLIBCXX_DEBUG anyway, I more often do something like:
#if 0
# include <debug/vector>
namespace my_class_stl = __gnu_debug;
#else
#include <vector>
namespace my_class_stl = std;
#endif
struct my_class
{
typedef my_class_stl::vector<int> container;
typedef container::iterator iterator;
// ...
};
Then I change the preprocessor condition when I want to use a Debug Mode vector for that specific class, without affecting every container in the program. Because the change involves writing to the file (and so updating its timestamp) anything that depends on that header will get rebuilt by make, and there are two distinct types, std::vector<int> and __gnu_debug::vector<int>, which have different symbols and can't be confused by the linker.
Just defining _GLIBCXX_DEBUG doesn't cause all dependencies to be rebuilt, and silently alters the definition of std::vector globally, rather than changing specific containers to a different type with a different name, __gnu_debug::vector
turned out to be caused by compiling a library with -D_GLIBCXX_DEBUG (which tells libstdc++ to use a debug version of the standard library with extra checks) but compiling the client program without.
It is an explicit libsdc++ debugging mode design goal to support such configuration, and I somewhat doubt that that was the actual cause of your problem.
The problem may have disappeared after you rebuilt the library without -D_GLIBCXX_DEBUG, but that doesn't prove that the ABI incompatibility was the root cause.

How can I compile some parts of C++/CLI code as Native and some part as Managed?

I am calling LoadTypeLib for loading unmanaged type libraries in C++/CLI. I need to compile some code areas as managed and some code areas as unmanaged (native) and form a mixed mode class library as executable.
What part do I need to be managed and unmanaged (native) to compile as managed and native respectively?
#pragma managed
Prefer using #pragma managed with push and on/off, then pop, #pragma unmanaged is actually quite useless.
Don't use #pragma managed - it's considered "evil" and may cause problems with DLL init/shutdown.
I would recommend explicitly compiling some files as managed (/clr), and some as native (without /clr). You can also have two pre-compiled headers - one for managed, one for native.

Producing small Windows binaries

When developing and deploying native Windows applications, I often need to install a runtime before being able to run my binary, or statically link the library with my binary. For instance, after building a "Win32 Console" project with Visual Studio 2008, attempting to run the program on a fresh Windows 7 image results in:
The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
Issues like this one have been brought up in other posts on StackOverflow.
How does one develop applications that don't require runtimes that aren't already on the target OS (i.e. don't require installing redistributable packages or private/shared side-by-side assemblies)? How does one avoid using msvc[mpr]90.dll and just use the Windows API in \windows\system32*.{dll,sys}?
I'm thinking along the lines of the code that comes out of the demoscene, but that's frequently not made available.
Others have already responded with respect to linking CRT statically. If you also want a small binary at the same time, then your best bet is forego CRT entirely, and use only Win32 API functions as much as possible. You'll still get some CRT code, most notably related to startup (i.e. that which calls main) and shutdown (atexit handling etc), but otherwise the linker won't link CRT functions that you do not use.
You can avoid linking CRT altogether by using /Zl compiler switch. This means that main will no longer work, however - you'll need to define WinMain (name doesn't matter, but signature must match, and it must be __stdcall), and you will have to specify the name of your WinMain-like function as an entry point via linker /entry: switch. This will save you ~30Kb of CRT code (tested on a .cpp with an empty main).
If you go the latter route, you might also have to deal with issue of compiler intrinsics. There are some functions that are nominally defined by the CRT (and declared in its headers), but which are treated specially by the compiler, so that it inserts optimized assembly instructions at the point of the call where possible - examples are memset, strlen, and a good chunk of functions in <math.h>; a complete list can be found here. Since you don't have CRT, if you need these functions, or could avoid it but prefer the intrinsic because of improved performance (hard to do better than memset, for example), then you have to declare them yourself, and use #pragma intrinsic. E.g.:
// Contains macros and typedef only, so safe to include without CRT.
// We need it here for size_t.
#include <stddef.h>
extern "C"
{
int abs(int);
void* memset(void*, int, size_t);
}
#pragma intrinsic(abs, memset)
int __stdcall main(void*, void*, char*, int)
{
char tmp[10];
memset(tmp, abs(-123), 10);
return 0;
}
The above can be compiled with:
cl /c /Zl foo.cpp
link /entry:main foo.obj
Link the CRT statically via the /MT switch (and likewise MFC, if you're using it).
Static linking limits what you can do with DLLs somewhat, but for simple executables it works like a charm. (And if you're shipping DLLs, you can always ship private assemblies anyway.)
Use the static CRT. This doesn't create a dependency on msvc*.dll. The CRT is linked directly into your program. This doesn't create dependencies, but does increase the size of your executable.
More info on different CRT options here.
Statically link the runtime. MS Visual C++ has option /MT for that (default is /MD)
I think one way to do this is to just not use Visual Studio and instead rely on the command line SDK tools. (You can alternatively figure out how to config VS to do what you want, but that seems harder.) E.g.:
cl /c app.cpp
link app.obj ws2_32.lib

Resources