Syntax for BluetoothLEDevice::RequestPreferredConnectionParameters() - c++

Using C++/WinRT, Win10, VS2019, SDK 10.0.22621.0, NuGet CppWinRT 2.0.220608.4
I'm trying to get the RequestPreferredConnectionParameters to work. At this point I am wondering if maybe I have the syntax wrong or maybe something else about it that I am not aware of. The MS docs for the function are here and the link to the various parameters are here.
The command line, as I have it, with pubDevice being the BLE device object, is:
BluetoothLEPreferredConnectionParametersRequest rcoConnect = pubDevice.RequestPreferredConnectionParameters(BluetoothLEPreferredConnectionParameters::ThroughputOptimized());
Just to mention, I am able to run
auto statusTest = co_await pubDevice.RequestAccessAsync();
before the RequestPreferredConnectionParameters without problems so, obviously, the device object is good and can be connected to.
What is happening is this. I have a function, OpenDevice(), that opens the device based on the address. If, after getting the device object, I issue the command above while still in the OpenDevice function, the code will not crash but it will immediately jump to the end of the OpenDevice() function bypassing all other lines of code below it and there will be no connection at all after that.
If I run the RequestPreferredConnectionParameters outside of the OpenDevice() function it errors out with a
An unhandled exception was encountered during a user callback and the line referenced is in base.h line 4942 if (result == impl::error_changed_state)
I had assumed that the callback refered to was the Rx Characteristic ValueChanged Callback that is set in OpenDevice(). So I tested by first revoking that callback with
pubRxCharacteristic.ValueChanged(etValueChangeToken);
and then running the RequestPreferredConnectionParameters but I still got the An unhandled exception error.
The only other callback that I have is the BluetoothLEAdvertisementWatcher advert received callback but that was stopped after the device was found.
Can anyone verify that my syntax seems correct and/or have any clue as to what is causing my problems?
EDIT to show more code in a console app------------
#IInspectable
Again for the record:
Using C++/WinRT, Win10, VS2019 - Console App, SDK 10.0.22621.0, NuGet CppWinRT 2.0.220608.4
Pertinent includes in the pch.h file:
// 2022/9/10 -- for WHCAR and apparently GUID
#include <Windows.h>
#include <tchar.h>
#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>
// 2022/9/10
#include <winrt\Windows.Devices.Enumeration.h>
#include <winrt/Windows.Foundation.Collections.h>
Pertinent name spaces at top of Main.cpp:
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;
// 2022/9/10 for RequestConnectionAsync
using namespace Windows::Devices::Enumeration;
I assume that the code to watch for and find the device is not pertinent here. Needless to say the device is found and the address is passed to OpenDevice to create the device object.
Here is the top portion of OpenDevice:
IAsyncAction OpenDevice(unsigned long long deviceAddress)
{
auto device = co_await BluetoothLEDevice::FromBluetoothAddressAsync(deviceAddress);
// 2022/9/10 test code
auto statusTest = co_await device.RequestAccessAsync();
// Allowed, DeniedBySystem, Unspecified
if (statusTest != DeviceAccessStatus::Allowed) {
std::cout << "Access to device is not allowed...." << std::endl;
}
else {
std::cout << "Access to device is allowed...." << std::endl;
}
// Next line ends without error but immediately goes to the end of OpenDevice()
std::cout << "Asking for ThroughputOptimized...." << std::endl;
auto statusConnection = device.RequestPreferredConnectionParameters(BluetoothLEPreferredConnectionParameters::ThroughputOptimized());
std::cout << "Line after Request ThroughputOptimized...." << std::endl;
Beep(500, 500);<br/> // function never gets to this cout or Beep<br/>
// More code follows to get Rx and TxCharacteristics etc.<br/>
} // end OpenDevice
Here is the console output:
Notice the last cout is the line Asking for ThroughputOptimized.
No cout for Line after Request ThroughputOptimized and no Beep.
Trying to locate the TENS device: Waiting for device:
AdvertisementReceived:
LocalName: []
AdvertisementType: [ConnectableUndirected]
BluetoothAddress: [0x300000e59630]
RawSignalStrengthInDBm: [-60] ServiceUUID: [0000fff0-0000-1000-8000-00805f9b34fb] Found TENS Device Main
Service.... TENS device found. Access to device is
allowed.... Asking for ThroughputOptimized....
WinRTBle.exe (process 15576) exited with code -1073740791. Press
any key to close this window .
Barring a problem in syntax or a missing header. the only other thing that I can think of is that it needs Win11. The docs for RequestPreferredConnectionParameters Method say
Windows requirements Device family Windows 11 (introduced in
10.0.22000.0)
Does that mean that regardless of the SDK it needs Win11?

#IInspectable As much as I was dreading this, apparently the answer is that it needs Win11. The console app code mentioned above in the edit to the original question was compiled into an exe. I have Win11 on a VM VirtualBox and I ran that exe on that Win11 and the code continued past the ThroughputOptimized() line in question and finished the rest of the app as expected. So that's ashamed. I don't have Win11 on a real box yet (call me paranoid) but I guess I could bracket the code for the Win11 OS and only run it when a user happens to be running Win11
Always something.......
EDIT 2 ...............................
And the "Always something" comes up immediately. As far as I can tell from what I have been able to find, there is no way to tell if the OS is Win10 or Win11. It was recommended to use RtlGetVersion but that returned 10 for both Win10 and Win11. Another poster suggested to use the File version of the System32 kernal32.dll file but they also both reported major number 10 and minor number 0. The MS docs for adding a version manifest had the UUIDs for both OSs as the same.
This is ridiculous that MS would come up with a function that only runs in Win11 and then not have to ability to tell you which OS you are running in....Jeeeeeeze.....
EDIT 3.........................
Spoke too soon. I was messing around with the console app and forgot that in my MFC app I use the WMI IWbemClassObject Caption property to get the OS.
For Windows 10 I get
Microsoft Windows 10 Pro
and for Win11 I get
Microsoft Windows 11 Home
So apparently that is really the only way to do it.

Related

winapi GetAsyncKeyState() does not work as described?

According to microsoft's documentation, GetAsyncKeyState() supposedly
Determines whether a key is up or down at the time the function is called
I've been building a UI automation library and the issue boils down to this
#include <Windows.h>
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
bool IsKeydownAsync(int key) {
return GetAsyncKeyState(key) & 0x8000;
}
int main(){
while (1) {
if (IsKeydownAsync('A')) {
cout << "triggered" << endl;
}
this_thread::sleep_for(chrono::milliseconds(10));
}
}
So my understanding is that it should not matter if my application is in focus or not, the GetAsyncKeyState() should always return whether the physical keys are up or down at the time of being called.
I have tested this over various applications and for most time it behaves as it is described. However, in some games this behavior breaks and it no longer reports whether the key is up or down. cout << "triggered" << endl doesn't get called when the key is held.
Is there something I overlooked?
It has been a while since I worked with native input in Windows, but from experience the Windows API functions only report key-states that are also reported using the synchronzied Windows API functionality, which is to say the normal application message/event input.
Some older games use previous versions of DirectX and alternative ways to capture input, e.g. using a library called the XInput(2) that has been deprecated since Windows 8.1 / 10. While both polling and events/msgs were supported, the input was caught using the DirectX thread and handled entirely differently compared to the Windows API. The main reason for this is that the OS tries to cater to all manufacturers, where the DirectX API did not specificcally address that issue for input.

How to prevent visual studio 2013 console window to close right after running a program? [duplicate]

This question already has answers here:
Keeping console window open when debugging
(3 answers)
Closed 8 years ago.
Hi I am using visual studio express 2013.I have never used vs before and so just to test it out I ran a simple c++ program where the user enters 2 integers and their sum is then displayed. The problem is that the console window appears and takes the inputs, but then immediately closes once the output is displayed. Please note that this happens right after all the inputs are taken and when the output is shown. Is there anyway to fix this? I have looked all over and cant find a solution. I have tried including a bunch of things such as the getch() function at the end of my program, and pressing ctrl F5 to debugg my programs,but nothing seems to work. Please help!!!
I have been using this,
int getchar ( void );
Get character from stdin
Returns the next character from the standard input (stdin).
OR
use this from process.h
system("PAUSE");
This approach is for beginners. It's frowned upon because it's a platform-specific hack that has nothing to do with actually learning programming, but instead to get around a feature of the IDE/OS - the console window launched from Visual Studio closes when the program has finished execution, and so the new user doesn't get to see the output of his new program.
One decent approach is Debug.WriteLine
// mcpp_debug_class.cpp
// compile with: /clr
#using <system.dll>
using namespace System::Diagnostics;
using namespace System;
int main()
{
Trace::Listeners->Add( gcnew TextWriterTraceListener( Console::Out ) );
Trace::AutoFlush = true;
Trace::Indent();
Trace::WriteLine( "Entering Main" );
Console::WriteLine( "Hello World." );
Trace::WriteLine( "Exiting Main" );
Trace::Unindent();
Debug::WriteLine("test");
}
In debug mode, Before your main return you could put a breakpoint and you will be able to see your console and the result you are waiting for.
Put
system("PAUSE");
wherever you need the program execution window to pause. If you're using int main(), usually it'll be right before you return 0

Error when calling EnterCriticalSection

I'm trying to create a mailbox on a Windows 7 OS in Eclipse IDE and in debug mode. I'm trying to create a RTOS(Real time operating system) like mailbox in Windows using Eclipse.
This is what my code for the mailbox looks like so far:
RTX_Mailbox RTX_CreateMailbox (unsigned long nSlotSize, unsigned long nSlots, char* szName)
{
::EnterCriticalSection (&csMailboxLock);
CMailBox* pNewMailbox = new CMailBox (nSlotSize, szName);
aMailBoxes.push_back (pNewMailbox);
RTX_Mailbox mailBox = ((unsigned int)aMailBoxes.size ()) - 1;
::LeaveCriticalSection (&csMailboxLock);
return mailBox;
}
My application keeps crashing on run-time as soon as it hits ::EnterCriticalSection(&csMailboxLock);
It returns this error message(highlighted in the pic attached):
Error message in text: No source available for ntdll!TpCallbackMayRunLong() at 0x77d78e19
Please let me know if further details are required...
So I did find a solution if anyone else had the same issue.
Turns out you need to initialize the Critical Section before you use it. So the following fixed it:
InitializeCriticalSection(&csMailboxLock);
This is the link that helped me:
https://sites.google.com/site/jeff00coder00seattle/home/coding/cpp-coding/c-win32-critical-section-example
The "error message" is not an error message, it simply indicates that the source for the current program-counter location (inside an OS call) is not available.
The documentation for EnterCriticalSection is pretty clear:
Before using a critical section, some thread of the process must call InitializeCriticalSection or InitializeCriticalSectionAndSpinCount to initialize the object.
I would advise consulting the documentation first in such cases.

Crash in windows XP with very simple gtk+cairo program

I am developing a Gtk application using gtkmm on Windows Vista with Visual Studio 2005. The application works fine on the development machine but I have received crash reports after it has been run on Windows XP machines (both Service Pack 2 and 3). I distribute the app with the directory structure described in http://live.gnome.org/gtkmm/MSWindows and it had given me no problems so far.
The crash gives no error messages except for Windows asking whether I want to report the error.
In order to solve the problem, I tried to compile the program against different versions of gtkmm (a recent stable version gtkmm-win32-devel-2.16.0-4 and an older version gtkmm-win32-devel-2.10.11-1) but the problem persisted.
I hunted down the problem to a call to window->create_cairo_context() inside the on_expose_event of a Gtk::DrawingArea. When I commented out this call, the problem would disappear. So I wrote the following minimal program, which still crashes:
#include <gtkmm.h>
#include <iostream>
class MyWindow : public Gtk::Window {
bool on_expose_event(GdkEventExpose* event) {
std::cout << "expose" << std::endl;
Glib::RefPtr<Gdk::Window> window = get_window();
if(window) {
std::cout << "win" << std::endl;
std::cout << "Get cairo" << std::endl;
Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
std::cout << "Get cairo done" << std::endl;
} else {
std::cout << "no win" << std::endl;
}
return true;
}
};
int main (int argc, char *argv[]) {
Gtk::Main m(argc,argv);
MyWindow w;
m.run(w);
return 0;
}
This minimal app may run and display the window without problem, but if I move the window off the screen limits or if I minimize/maximize it enough times (thus triggering calls to on_expose_event), it will eventually crash. It may also be the case that it won't crash the first time, but it will crash after restarting the app and triggering multiple calls to on_expose_event as described above. One thing I've noticed is that the app crashes after printing "Get cairo done". When I comment out the call to create_cairo_context, the problem dissapears, so I'm pretty sure there is something wrong with this line.
The error happens on clean installed Windows XP machines. I have tested both apps (original and minimal) on a colleague's notebook, which also has Windows XP, but it doesn't crash there. I suppose there is some dependency that is available/up to date in our computers but not in the computers where the application crashes. I have updated DirectX and installed Visual Studio C++ 2005 Redistributable on one of the problematic machines, but the problem persists.
The original app, which draws a graph on the DrawingArea, doesn't necessarily crash the first time either. It may work fine the first time after rebooting, but is more prone to fail the second time.
I am thinking about compiling and testing with MinGW to see if that solves the problem. I'll also try to compile a debug version and try to use a debugger. I have suspected the version of gdi32.dll might have something to do, seeing that libcairo-2.dll depends on this dll according to Dependency Walker, but until now it's just an speculation. Other than that, I'm out of ideas.
I'll be trying these ideas for the time being. Hopefully someone has more suggestions or knows what is going on with the code above.

How to output to the console in C++/Windows

When using iostream in C++ on Linux, it displays the program output in the terminal, but in Windows, it just saves the output to a stdout.txt file. How can I, in Windows, make the output appear in the console?
Since you mentioned stdout.txt I google'd it to see what exactly would create a stdout.txt; normally, even with a Windows app, console output goes to the allocated console, or nowhere if one is not allocated.
So, assuming you are using SDL (which is the only thing that brought up stdout.txt), you should follow the advice here. Either freopen stdout and stderr with "CON", or do the other linker/compile workarounds there.
In case the link gets broken again, here is exactly what was referenced from libSDL:
How do I avoid creating stdout.txt and stderr.txt?
"I believe inside the Visual C++ project that comes with SDL there is a SDL_nostdio target > you can build which does what you want(TM)."
"If you define "NO_STDIO_REDIRECT" and recompile SDL, I think it will fix the problem." > > (Answer courtesy of Bill Kendrick)
For debugging in Visual Studio you can print to the debug console:
OutputDebugStringW(L"My output string.");
If you have a none-console Windows application, you can create a console with the AllocConsole function. Once created, you can write to it using the normal std::cout methods.
If you're using Visual Studio you need to modify the project property:
Configuration Properties -> Linker -> System -> SubSystem.
This should be set to: Console (/SUBSYSTEM:CONSOLE)
Also you should change your WinMain to be this signature:
int main(int argc, char **argv)
{
//...
return 0;
}
The AllocConsole Windows API function will create a console window for your application.
If you're using Visual Studio, it should work just fine!
Here's a code example:
#include <iostream>
using namespace std;
int main (int) {
cout << "This will print to the console!" << endl;
}
Make sure you chose a Win32 console application when creating a new project. Still you can redirect the output of your project to a file by using the console switch (>>). This will actually redirect the console pipe away from the stdout to your file. (for example, myprog.exe >> myfile.txt).
I wish I'm not mistaken!
Whether to use subsystem:console or subsystem:windows kind of depends on whether how you want to start your application:
If you use subsystem:console, then you get all of the stdout written to the terminal. The trouble is that if you start the application from the Start Menu/Desktop, you (by default) get a console appearing as well as the application window (which can look pretty ugly).
If you use subsystem:windows, you won't get stdout/stderr even if you run the application from a DOS window, Cygwin, or other terminal.
If you want the middle way which is to output to the terminal IF the application was started in a terminal, then follow the link that Luke provided in his solution (http://dslweb.nwnexus.com/~ast/dload/guicon.htm)
For reference, I ran into this problem with an application that I want to run in either normal Windows mode or batch mode (that is, as part of a script) depending on command-line switches. The whole differentiation between console and Windows applications is a bit bizarre to Unix folks!
First off, what compiler or dev environment are you using? If Visual Studio, you need to make a console application project to get console output.
Second,
std::cout << "Hello World" << std::endl;
should work in any C++ console application.
Your application must be compiled as a Windows console application.
There is a good solution
if (AllocConsole() == 0)
{
// Handle error here. Use ::GetLastError() to get the error.
}
// Redirect CRT standard input, output and error handles to the console window.
FILE * pNewStdout = nullptr;
FILE * pNewStderr = nullptr;
FILE * pNewStdin = nullptr;
::freopen_s(&pNewStdout, "CONOUT$", "w", stdout);
::freopen_s(&pNewStderr, "CONOUT$", "w", stderr);
::freopen_s(&pNewStdin, "CONIN$", "r", stdin);
// Clear the error state for all of the C++ standard streams. Attempting to accessing the streams before they refer
// to a valid target causes the stream to enter an error state. Clearing the error state will fix this problem,
// which seems to occur in newer version of Visual Studio even when the console has not been read from or written
// to yet.
std::cout.clear();
std::cerr.clear();
std::cin.clear();
std::wcout.clear();
std::wcerr.clear();
std::wcin.clear();
I assume you're using some version of Visual Studio? In windows, std::cout << "something"; should write something to a console window IF your program is setup in the project settings as a console program.
If using MinGW, add an option, -Wl,subsystem,console or -mconsole.
You don't necessarily need to make any changes to your code (nor to change the SUBSYSTEM type). If you wish, you also could simply pipe stdout and stderr to a console application (a Windows version of cat works well).