Universal Windows Platform (UWP) API Call from C native console application - crash
Hi!
Based on Microsoft Universal Samples (https://github.com/microsoft/Windows-universal-samples) I've created a static library(.lib) for geolocating on Windows 10/11. The library is linked into a Windows console application (.exe). I've tried with multiple toolsets (v142, v143), Windows SDK versions and various other configurations but the console application crashes randomly when trying to call my library function (library is written in C++17, the excutable in C). It seems that it crashes more often if I call the library function from a thread in the main application (created with _beginthreadex).
What am i doing wrong?
My library code is this:
#include <winrt/Windows.Devices.Geolocation.h>
#include <winrt/Windows.Foundation.h>
using namespace winrt;
using namespace Windows::Devices::Geolocation;
using namespace Windows::Foundation;
#ifdef __cplusplus
extern "C" {
#endif
int test_win_rt(double* latitude, double* longitude, double* accuracy)
{
*latitude = 0;
*longitude = 0;
*accuracy = 0;
int result = 0;
try {
// Initialize the Windows Runtime
winrt::init_apartment(apartment_type::multi_threaded);
// Create a Geolocator object
Geolocator geolocator;
// Request permission to access location
auto accessStatus = geolocator.RequestAccessAsync().get();
switch (accessStatus)
{
case GeolocationAccessStatus::Allowed:
{
geolocator.ReportInterval(2000);
Geoposition pos = geolocator.GetGeopositionAsync().get();
// Extract latitude, longitude and accuracy
*latitude = pos.Coordinate().Point().Position().Latitude;
*longitude = pos.Coordinate().Point().Position().Longitude;
*accuracy = pos.Coordinate().Accuracy();
}
break;
case GeolocationAccessStatus::Denied:
result = 1;
break;
case GeolocationAccessStatus::Unspecified:
result = 2;
break;
}
// Clean up
winrt::uninit_apartment();
}
catch ([[maybe_unused]] winrt::hresult_error const& ex)
{
winrt::uninit_apartment();
result = 3;
}
return result;
}
#ifdef __cplusplus
}
#endif
It crashes here, on the check_hresult line, in base.h:
namespace Windows::Foundation
{
struct IActivationFactory : IInspectable
{
IActivationFactory(std::nullptr_t = nullptr) noexcept {}
IActivationFactory(void* ptr, take_ownership_from_abi_t) noexcept : IInspectable(ptr, take_ownership_from_abi) {}
template <typename T>
T ActivateInstance() const
{
IInspectable instance;
check_hresult((*(impl::abi_t<IActivationFactory>**)this)->ActivateInstance(put_abi(instance)));
return instance.try_as<T>();
}
};
}