我需要将本机C ++代码与C ++ CX代码结合起来。我们的产品主要是本机C ++,我需要访问win10功能(PushNotifications)。但是此功能是用WinRT编写的,因此可以从C ++ CX,C#等访问,但不能直接从C ++访问。
是的,我知道您现在会告诉我这是可能的,因为C ++ CX最终被编译为本机代码。在这种情况下,请检查我以前的帖子。CreatePushNotificationChannelForApplicationAsync in native C++
所以我正在寻找其他选择。我想创建C ++ CX DLL,然后将其加载到C ++本机应用程序中。但是我也失败了,因为我无法在C ++ CX类中使用本机回调。我需要注册将在通知到来时触发的回调或接口。但是我无法注册。因为本机指针不能成为C ++ CX类的公共接口的一部分。
我有两个问题:
UPDATE:我发现了如何解决编译器错误,但仍然无法正常工作。声明使用本机指针作为私有成员的成员函数,然后声明可以访问此私有成员的friend
函数。
现在我遇到错误:HRESULT_FROM_WIN32(ERROR_NOT_FOUND) : Element not found.
,与本机方法相同。
也许是我的应用程序未与Win Store应用程序关联。但是我创建了UWP应用程序,但没有将其与Win Store关联,并且可以正常工作。所以我真的不知道可能是什么问题。
这里是简化代码:
标题(DLL接口的声明)
#pragma once
#include <string>
class IEventHandler
{
public:
virtual void UriRefreshAsync(std::wstring&& uri) = 0;
virtual void OnNotify(std::wstring&& content) = 0;
};
extern "C"
{
__declspec(dllexport) void RegisterEventHandler(IEventHandler* handler);
}
定义(用/ZW
编译的DLL定义]
#include <windows.h>
#include <collection.h>
#include <ppltasks.h>
#include <wrl.h>
#include <wrl/wrappers/corewrappers.h>
#include "wns.h"
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Networking::PushNotifications;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace concurrency;
namespace WnsPushAPI
{
public ref class WnsWrapper sealed
{
public:
WnsWrapper() : winRT(RO_INIT_MULTITHREADED) {};
static WnsWrapper^ Instance() { return singleton ? singleton : singleton = ref new WnsWrapper(); }
void ObtainUri()
{
IAsyncOperation<PushNotificationChannel^>^ channelOperation = PushNotificationChannelManager::CreatePushNotificationChannelForApplicationAsync();
auto channelTask = create_task(channelOperation);
channelTask.then([this](PushNotificationChannel^ channel) {
eventHandler->UriRefreshAsync(std::wstring(channel->Uri->Data()));
channel->PushNotificationReceived += ref new TypedEventHandler<PushNotificationChannel^, PushNotificationReceivedEventArgs^>(this, &WnsWrapper::OnNotify);
}, task_continuation_context::use_current());
}
void OnNotify(PushNotificationChannel^ sender, PushNotificationReceivedEventArgs^ e)
{
if ( e->NotificationType == PushNotificationType::Raw )
{
eventHandler->OnNotify(std::wstring(e->RawNotification->Content->Data()));
}
e->Cancel = true;
};
private:
void RegisterEventHandler(IEventHandler* handler) { eventHandler = handler; };
friend void ::RegisterEventHandler(IEventHandler* handler);
RoInitializeWrapper winRT;
IEventHandler* eventHandler = nullptr;
std::wstring uri;
static WnsWrapper^ singleton;
};
WnsWrapper^ WnsWrapper::singleton = nullptr;
}
void RegisterEventHandler(IEventHandler* handler)
{
WnsPushAPI::WnsWrapper::Instance()->RegisterEventHandler(handler);
}
void GetUriAsync()
{
WnsPushAPI::WnsWrapper::Instance()->ObtainUri();
}
Main(本地C ++应用程序)
#include "../wns/wns.h"
#include <windows.h>
#include <iostream>
using namespace std;
class Events : public IEventHandler
{
public:
virtual void UriRefreshAsync(std::wstring&& uri)
{
wcout << uri << endl;
};
virtual void OnNotify(std::wstring&& content) { /*trigger notify*/ };
};
int main(char* argv[], int argc)
{
Events events;
RegisterEventHandler(&events);
GetUriAsync();
Sleep(100*1000);
return 0;
}
如果使用的是Visual Studio,则可以为非WinRT应用程序启用C ++ CX支持。为此,请转到“属性”->“ C / C ++”,然后选择“将Windows Runtime Extensions消耗为“是(/ ZW)”。