How to all C++/WinRT from UMDF2 - c++

I develop an UMDF2.0 driver using VS2019.
Inside this driver I need to communicate with an BLE device.
I have to use BluetoothLEDevice class to do this. This is a WinRT Api.
I'm completely lost on how to call C++/WinRT from my driver.
Does anyone have experienced this situation ?
Thank a lot for your great support,
EDIT 1#
I use the following simple test code in new cpp file into umdf2 sample project:
#include <windows.devices.h>
#include <windows.devices.bluetooth.h>
#include <windows.devices.bluetooth.genericattributeprofile.h>
using namespace ABI::Windows::Devices::Bluetooth;
void testBle()
{
BluetoothLEDevice dev;
}
I have the following error :
Error C2079
'dev' uses a class of 'ABI::Windows::Devices::Bluetooth::BluetoothLEDevice' not defined
EDIT 2
I found one usefull project on GitHub that help me a lot to make all this work. Please find the link below :
https://github.com/bucienator/ble-win-cpp
Thank you again for your help

You cannot instantiate the BluetoothLEDevice with default constructor because there is no such constructor in this case.
Please use this code snippet in instantiate the BT device.
#include <winrt/windows.devices.h>
#include <winrt/Windows.Devices.Bluetooth.h>
using namespace Windows::Devices::Bluetooth;
void testBle()
{
BluetoothLEDevice btDev = NULL;
IAsyncOperation<BluetoothLEDevice> launchOp =
BluetoothLEDevice::FromIdAsync(L"test");
btDev = launchOp.GetResults();
}

Related

Using WRL to access WinRT, I cannot get ActivateInstance to work

I am trying to figure out how to access the WinRT API via WRL in C++, using visual studio 2022 with the latest update 17.1.2.
(Background: I've done a fair amount of old-fashioned Windows desktop programming with the Win32 API. However, I now wish to access parts of the Windows API that are supported only in WinRT, such as access to Bluetooth LE devices. Note that I am trying to avoid UWP applications, as I fear it may cause my applications to be bloated, and am not sure what needed functionality it might remove from my programs. Further, I have tried Microsoft's C++/WinRT, but was having lots of trouble at points where the Microsoft compiler was telling me there was a problem up in the generated C++ headers--not my own code. So I am now trying to work closer to the ground with WRL.)
So, starting with an example provided in MS documentation (uri winRT class, which I can get to work as they wrote it), I have tried to try use of the ActivateInstance WRL class (which is not used in their example).
It seems not to be working for me. But I am probably doing something wrong. Can anyone help?
I have pared down the code to show the precise issue:
#include <roapi.h>
#include <combaseapi.h>
#include <iostream>
#include <windows.foundation.h>
#include <windows.foundation.collections.h>
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <stdio.h>
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
int dummy;
ComPtr<IUriRuntimeClassFactory> uriFactory;
ComPtr<IUriRuntimeClass> uri;
HRESULT hr, hr2;
int main()
{
// Initialize the Windows Runtime.
RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
// Get the activation factory for the IUriRuntimeClass interface.
hr = GetActivationFactory(HStringReference(L"Windows.Foundation.Uri").Get(), &uriFactory);
hr2 = ActivateInstance (HStringReference(L"Windows.Foundation.Uri").Get(), &uri);
dummy = 1;
}
What happens is hr returns as S_OK. (Creating the factory. I don't use it here, but it is apparently a valid factory as it works when I leave in the rest of the Microsoft WRL example.)
But, what is confusing me is that hr2 is returning "E_NOTIMPl (not implemented)", and I thought it would get me a smart pointer to the uri class.
(Referencing this MS documentation for ActivateInstance:
and observing that the argument types are the same as
for GetActivationFactory
Thanks

How do I use 'StartTranscriptionJobRequest' from the AWS Transcribe C++ API?

I am having some difficulty with AWS Transcribe for C++. I believe a simple code example would solve it for me, but I find no code examples of the AWS Transcribe API in C++, (I realize there is one for TranscribeStreamingService, but my task is far simpler.)
According to the AWS docs for TranscribeServiceClient and StartTranscriptionJobRequest I need to create a StartTranscriptionJobRequest object, fill it in with setters, and hand it to the TranscribeServiceClient like this:
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentialsProviderChain.h>
#include <aws/core/client/AWSClient.h>
#include <aws/transcribe/TranscribeServiceClient.h>
using namespace Aws;
using namespace Aws::TranscribeService;
using namespace Aws::TranscribeService::Model;
void TestAWSTranscript() {
Aws::SDKOptions options;
Aws::InitAPI(options);
{
Aws::Client::ClientConfiguration config;
TranscribeServiceClient TranscriptClient(Auth::AWSCredentials(user_access_key.c_str(), user_private_key.c_str()), config);
StartTranscriptionJobRequest request = new StartTranscriptionJobRequest();
// request.SetLanguageCode(Aws::TranscribeService::Model::LanguageCode::en_US);
// more setters here...
TranscriptClient.StartTranscriptionJob(&request);
// check for completion
// enjoy transcript...
}
Aws::ShutdownAPI(options);
}
but the line:
StartTranscriptionJobRequest request = new StartTranscriptionJobRequest();
produces the errors:
Allocation of incomplete type 'Aws::TranscribeService::Model::StartTranscriptionJobRequest'
Variable has incomplete type 'Aws::TranscribeService::Model::StartTranscriptionJobRequest'
If it helps, the aws sdk is open-source and available on git.
What am I misunderstanding?
incomplete type means the complete class definition is not available/the class is only forward declared.
adding
#include <aws/transcribe/model/StartTranscriptionJobRequest.h>
should fix this

co_await expression needs await_ready function

I have a Win32 programm, where I want to add some winRT calls. Among other things I want to open a file without a GUI interface.
I use the async file open call from the StorageFile class, because the next call needs an IStorageFile interface.
#include <roapi.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Foundation.h>
void openFile()
{
using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Storage;
HRESULT rtn = RoInitialize(RO_INIT_MULTITHREADED);
winrt::hstring path{ L"C:\\Users...\\mytextfile.txt"};
//wait for open the file
auto file = co_await StorageFile::GetFileFromPathAsync(path);
//IStorageFile interface needed
}
int main()
{
openFile();
return 0;
}
At the moment, the compiler complains that the co_await expression requires a suitable "await_ready" function and none was found.
I`m not sure if this is the case due to a missing header include or if "co_await" can not be used within a win32 application.
Edit:
My visual studio project setup is:
- use c++17, add cppwinrt.exe to my include directories, link against windowsapp.lib and use windows sdk version 10.0.17134.0.
The problem is that the openFile() function does not have the proper return type to handle co_await.
See the research and work that went into the answer I created for C++11 threads to update MFC application windows. SendMessage(), PostMessage() required? which contains a list of recommendations for various approaches to coroutines.
This question was about using C++/WinRT with MFC but the material also applies with WinAPI.
See as well synchronizing SDK with Windows 10 update and using WinRT with Standard C++ which contains a simple console application example using the Web Syndication async functionality to retrieve a list of URLs from an RSS feed. There are a number of links to documentation, some of which is a bit out dated now.
Addendum: Sample Console application
I created the following simple console application using Visual Studio 2017. I created the text file and then ran this in the debugger. I then renamed the text file and ran it again in the debugger and an exception was thrown since the file with that name no longer existed.
See also C++/WinRT, part of Windows SDK 17134 is not compatible with Visual Studio 15.8 Preview 3 which describes a compiler option you may need to change. I did.
// console_winrt.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
// Requires the following changes to the project properties in the C++ compiler section.
// - C++ language standard must be set to C++17
// - Add /await to the Additional options
#include "pch.h"
#pragma comment(lib, "windowsapp")
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Foundation.h>
#include <iostream>
winrt::Windows::Foundation::IAsyncAction openMyFile()
{
winrt::hstring path{ L"D:\\Users\\rickc\\mytextfile.txt" };
//wait for open the file
auto file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path);
//IStorageFile interface needed
auto xDate = file.DateCreated();
std::cout << "file was found " << std::endl;
}
int main()
{
// initialize the WinRT apartment.
winrt::init_apartment();
auto x = openMyFile();
// wait on the file access since that is all we are doing and we need to give it time.
x.get();
return 0;
}
I used the following properties settings.

How to use namespace - Microsoft.Phone.Info - in native C++ on in WP 8.1 or WP 8

I'm working in a native C++ enviroment on WP8.1.
Let's say I want to call a functions like
Microsoft.Phone.Info::DeviceExtendedProperties.GetValue( "DeviceUniqueId" );
The problem is no matter how I try, it didn't pass compile.
I know "Microsoft.Phone.Info" is a name space,
in C# ppl wrote:
using Microsoft.Phone.Info;
but in C++, I tried
using namespace Microsoft.Phone.Info;
void func()
{
DeviceExtendedProperties.GetValue("DeviceUniqueId");
}
didn't pass compile. or
void func()
{
Microsoft.Phone.Info::DeviceExtendedProperties.GetValue("DeviceUniqueId");
}
didn't pass compile.
It keeps telling me something like this
'Microsoft' : illegal use of namespace identifier in expression
so how do I use this namespace properly?
Thank you guys for the reading and answering. :-)
I can't find a C++ example for retriving the device ID. :-P
Although many of the properties from DeviceInformation can be found on EasClientDeviceInformation, the device ID is not one of them. Instead, you should look at using the ASHWID which will get you an app-specific hardware ID.
In native WP runtime, using a namespace follows this syntax
using namespace Windows::Phone::Info;
But you will find out that the namespace does not exist in runtime. Only in WP Silverlight.
So you can look at this MSDN webpage that tells you where they moved all the functionality from 8.0 SL to 8.1 runtime.
Windows Phone Silverlight to Windows Runtime namespace and class mappings
Then if you search for "Windows.Phone.Info" it will lead you to the new functions you should call.
Here is the ID : EasClientDeviceInformation class
I guess I got it:
EasClientDeviceInformation^ deviceInfo = ref new EasClientDeviceInformation();
deviceInfo->Id; //<- is what I want

Problem debugging C++ with an Eclipse based IDE

This is a weird question in that I'm not sure where to start looking.
First of all, I haven't done any C++ programming for the last 10 years so it could be me thats forgotten a few things. Secondly, the IDE I'm using is Eclipse based (which I've never used) and customized for Samsung bada based mobile development (it kicks off an emulator for debugging purposes)
I'm posting my code samples as images because the StackOverflow WYSIWYG editor seems to have a problem parsing C++.
[EDIT] Due to complaints I've edited my question to remove the images. Hope that helps :)
I have the following header file...
#include <FApp.h>
#include <FBase.h>
#include <FGraphics.h>
#include <FSystem.h>
#include <FMedia.h>
using namespace Osp::Media;
using namespace Osp::Graphics;
class NineAcross :
public Osp::App::Application,
public Osp::System::IScreenEventListener
{
public:
static Osp::App::Application* CreateInstance(void);
public:
NineAcross();
~NineAcross();
public:
bool OnAppInitializing(Osp::App::AppRegistry& appRegistry);
private:
Image *_problematicDecoder;
};
...and the following cpp file...
#include "NineAcross.h"
using namespace Osp::App;
using namespace Osp::Base;
using namespace Osp::System;
using namespace Osp::Graphics;
using namespace Osp::Media;
NineAcross::NineAcross()
{
}
NineAcross::~NineAcross()
{
}
Application* NineAcross::CreateInstance(void)
{
// Create the instance through the constructor.
return new NineAcross();
}
bool NineAcross::OnAppInitializing(AppRegistry& appRegistry)
{
Image *workingDecoder;
workingDecoder->Construct();
_problematicDecoder->Construct();
return true;
}
Now, in my cpp file, if I comment out the line that reads _problematicDecoder->Construct();...I'm able to set a breakpoint and happily step over the call to Constuct() on workingDecoder. However, as soon as I uncomment the line that reads _problematicDecoder->Construct();... I end up with the IDE telling me...
"No source available for "Osp::Media::Image::Construct()"
In other words, why can I NOT debug this code when I reference Image *image from a header file?
Any ideas?
Thanks :-)
This usually means you're stepping through some code which you do not posses its source.
I assume here that Osp::Media::Image is a class supplied by Samsung or similar for which you do not have the cpp file. So this means the debugger can't show you the current code line while you're at a function of Osp::Media::Image.
Alternatively, there's a good chance you do have all of the source code for this class, but Eclipse doesn't know where it is. In this case you can add the correct directories under the Debug Configurations window.
Ok, problem solved.
The idea is to first new up an instance of Image like so...
_decoder = new Osp::Media::Image();
And then do _decoder->Construct().
Funny enough, this seems blatantly obvious to me now coming from the C# world, though why the code I posted for workingDecoder works is still somewhat mysterious to me. The fact the sample projects pre-loaded with the bada IDE don't seem to make a call to new() leads me to believe that perhaps those samples are outdated our out of synch.
Either that or I really AM wildly out of the C++ loop.
Anyway thanks so much for the effort guys.
Appreciated :)