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
Related
C++, WinRT, VS2017, Windows10, Bluetooth LE
I have a stand-alone C++/WinRT VS2017 console app that was used for testing code to control a Bluetooth LE device. That console app works and I am now in the process of moving that code into an existing C++ MFC VS2017 app which also works.
In the existing MFC app I first installed the NuGet cppwinrt package that I used in the test console app (no problems)
I then put the various WinRt header files that were in the console app's pch.h into the MFC's stdafx.h file
#pragma comment(lib, "windowsapp")
#include <condition_variable>
#include "winrt\Windows.Foundation.h"
#include "winrt\Windows.Storage.Streams.h"
#include "winrt\Windows.Devices.Bluetooth.h"
#include "winrt\Windows.Devices.Bluetooth.Advertisement.h"
#include "winrt\Windows.Devices.Bluetooth.GenericAttributeProfile.h"
So far, so good. The MFC app still compiles without problems. However, I then put the "using namespace" entries, that were at the top of the console app's .cpp file, into the MFC's ...View.cpp and that is when I get the compile problems
using namespace winrt;
using namespace Windows::Foundation;
using namespace winrt::Windows::Foundation;
using namespace Windows::Storage::Streams;
using namespace Windows::Devices::Bluetooth;
using namespace Windows::Foundation::Collections;
using namespace Windows::Devices::Bluetooth::Advertisement;
using namespace Windows::Devices::Bluetooth::GenericAttributeProfile;
The compile error I get is:
Error C2872 'IUnknown': ambiguous symbol MyMFCApp c:\program files
(x86)\microsoft visual
studio\2017\professional\vc\tools\msvc\14.16.27023\atlmfc\include\atlcom.h 3456
I see that IUnknown seems to be fairly universal throughout Windows APIs. How should I go about clearing up this error?
#AlanBirtles answer seems to have solved the problem. In the console app I could not compile without these using namespace entries so I just assumed that I would also need them in the MFC app. As I mentioned in my comment above, all of the namespaces compiled in the MFC app except for the two Foundation namespaces.
//using namespace Windows::Foundation; // errors IUnknown
//using namespace winrt::Windows::Foundation; // errors IUnknown
I left the rest and commented these two out and then added the code to create the BluetoothLEAdvertisementWatcher, attach a callback for the watcher.Received() and let it find my device. It ran fine. I have not yet tried with the rest of the namespaces commented out but I will.
I did try #IInspectable suggestion for using the #include <unknwn.h> before all of the WinRT namespaces. I put that in at the top and then uncommented one of the two Foundation namespaces but still got the ambiguous IUnknown error.
So the answer seems to be (for my situation anyway) that the namespaces were not necessary...at least the two Foundation namespaces.
Thanks for the help. It is really appreciated.
With C++/WinRT Microsoft apparently made quite the effort to make their APIs standard-conformant.
And finally they've also released a machine learning API along with a code sample repo.
Unfortunately, all samples are dependent on Visual Studio. Even the simplest command line demo (CustomTensorization) requires .snl files and VisualStudio.
Is it possible to write code for this API without VisualStudio by just downloading an SDK and using a regular make file?
If so, how? Please post or point to a MCVE.
Thank you.
I don't know anything about the machine learning API, but C++/WinRT is a header-only library that you can include and build from a developer command prompt quite easily. Here's a simple example:
C:\ml>type sample.cpp
#pragma comment(lib, "windowsapp")
#include <winrt/Windows.AI.MachineLearning.h>
#include <stdio.h>
using namespace winrt;
using namespace Windows::AI::MachineLearning;
int main()
{
init_apartment();
puts("Sample");
}
C:\ml>cl /EHsc /std:c++17 /nologo sample.cpp
sample.cpp
C:\ml>sample.exe
Sample
For an actual example using the machine learning API I'd suggest you start here:
https://learn.microsoft.com/en-us/windows/ai/get-started-desktop
But again, you can follow along and substitute Visual Studio with the command line and use cmake, or any other build system, if so desired.
I am currently using Graphics, Image, Color, and Bitmap Gdi+ classes in my C++ Application, but whenever I try to use BrightnessContrast and BrightnessContrastParams I get errors:
In Intellisense: Error: Namespace 'Gdiplus' has no member 'BrightnessContrast'
When Compiling: 'BrightnessContrast' : is not a member of 'Gdiplus'
What gives? I did find a forum post that said to add a line to "Additional Manifest Dependencies:" in the project properties, I did this but it still didn't work. The post goes on to say try looking in %windir%\winsxs if that doesn't work but I don't see how to make sense of the files in that directory. I am using VisualStudio 2010 on Windows7 64bit.
Also, I am aware that I can create my own Brightness and Contrast functions. I am wondering why I can't use the build-in Classes that are documented on MSDN.
Thanks
These members are only available in GDI+ version 1.10, the version that shipped first with Vista. You have to explicitly opt-in to use them. Like this:
#define GDIPVER 0x110
#include <gdiplus.h>
Beware that your program won't run on XP when you do this.
I'm wondering how Visual Studio, other IDE's, and any other sort of circumstances (ie. no IDE at all) handle bringing in code from outside.
At first I thought #includes were the only way to do this, by either placing the assembly files in the designated directory for Visual Studio assembly files and then using the <> format to bring them in, or by putting the assembly files in the project directory and using the "" format to bring them in (that is, <> and "" respectively). But now I come up to the example at the end of this post with the #using directive (which, to note, is different than just the 'using' directive without the '#', for namespaces). Also I've come across adding assembly references in visual studio from within the 'configuration properties' dialogue.
So, would someone set me straight on all the in's and out's of adding assembly files and other code to a given project?
--The following is the example that has confused me-->
I have this section in my book that states:
"...The figure combines C++ 2008 code
with legacy C and native C++ code. It
also presents the two assembly
reference files you'll use most often
with C++ 2008, along with their
associated namespaces. Unlike when
you use Visual Studio to develop a
project, the assembly reference files
aren't included by default when you
code a single source file. Because of
that, you must code #using directives
for these files. ..."
#include <stdio.h>
#include <iostream>
#using <system.dll>
#using <system.windows.forms.dll>
// Associated namespace directives
using namespace std;
using namespace System;
using namespace System::Windows::Forms;
void main()
{
printf( "Hello, Earth\n"); // from stdio.h
cout << "Hello, Mars\n"; // from iostream
Console::WriteLine("Hello, Jupiter"); // from system.dll
MessageBox::Show ("Hello, Saturn"); // from system.windows.forms.dll
}
This is not native C++ (usually just referred to as C++), but C++/CLI, which is actually a .NET language designed to ease interacting between native and managed code, and as such can use both. It is, however, definitely not C++, despite an intentionally strong resemblance. Assemblies are .NET managed code repositories. You use the #using command to use them. #include is for native C++ headers. You should also be able to add managed references (that is, #using but done throughout for you) from the project's properties.
In native C++, then you must #include headers, and if appropriate, link to .lib files (or use GetProcAddress manually), and Visual Studio also offers #import for COM libraries. C++/CLI also offers #using for bringing in managed assemblies.
void main()
{
printf( "Hello, Earth\n"); // C native code
cout << "Hello, Mars\n"; // C++/CLI's wrapper on C++ Standard
Console::WriteLine("Hello, Jupiter"); // .NET managed code
MessageBox::Show ("Hello, Saturn"); // A thin wrapper on WinAPI
}
If you don't already know both C++ and .NET code, and/or you're not trying to link the two together, it's not recommended to use C++/CLI.
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.