與眾不同 windows phone (48) - 8.0 其它: C# 調用 C++
作者:webabcd
介紹
與眾不同 windows phone 8.0 之 其它
- C# 中調用 Windows Phone Runtime Component(C++)
- 讓 Windows Phone Runtime Component(C++) 作為代理以調用 DLL(C++)
- 通過 C++ 和 D3D 獲取屏幕分辨率
示例
一、演示如何在 C# 中調用 Windows Phone Runtime Component(C++),以及 Windows Phone Runtime Component(C++) 如何作為代理調用 DLL(C++)
1、PhoneDLL 項目
PhoneDLL.h
#pragma once // 用於演示 C# 調用 Windows Phone Dynamic Link Library(C++) 中的函數(需要通過 Windows Phone Runtime Component 做為代理) extern "C" _declspec(dllexport) int Add(int x, int y);
PhoneDLL.cpp
#include "pch.h" #include "PhoneDLL.h" int Add(int x, int y) { return x + y; }
2、WPRuntimeComponent 項目
WPRuntimeComponent.h
#pragma once #include <windows.h> using namespace Platform; namespace WPRuntimeComponent { public ref class WindowsPhoneRuntimeComponent sealed { public: // 用於演示 C# 調用 Windows Phone Runtime Component(C++) 中的函數 int Add(int x,int y); // 用於演示通過此 Windows Phone Runtime Component 做為代理,然后調用 Windows Phone Dynamic Link Library(C++) 中的函數 typedef int(*myAdd)(int x,int y); int Add2(int i,int j); }; }
WPRuntimeComponent.cpp
#include "pch.h" #include "WPRuntimeComponent.h" using namespace WPRuntimeComponent; using namespace Platform; int WindowsPhoneRuntimeComponent::Add(int x, int y) { return x + y; } // 作為代理,調用 PhoneDLL.dll 中的函數 int WindowsPhoneRuntimeComponent::Add2(int i,int j) { HINSTANCE hDll = LoadPackagedLibrary(L"PhoneDLL.dll",0); myAdd add = (myAdd)GetProcAddress(hDll, "Add"); int result = add(i, j); FreeLibrary(hDll); return result; }
3、調用者
CPP/Demo.xaml
<phone:PhoneApplicationPage x:Class="Demo.CPP.Demo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <Grid Background="Transparent"> <StackPanel> <TextBlock x:Name="lblMsg" TextWrapping="Wrap" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
CPP/Demo.xaml.cs
/* * 演示如何在 C# 中調用 Windows Phone Runtime Component(C++),以及 Windows Phone Runtime Component(C++) 如何作為代理調用 DLL(C++) * * * 注: * 1、Windows Phone Runtime Component(C++) 項目參見:WPRuntimeComponent 項目 * 2、DLL(C++) 項目參見:PhoneDLL 項目 * 3、將 PhoneDLL.dll 復制到本項目的根目錄下,以便 WPRuntimeComponent 項目調用 */ using System; using System.Windows.Navigation; using Microsoft.Phone.Controls; namespace Demo.CPP { public partial class Demo : PhoneApplicationPage { public Demo() { InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { // 引用 Windows Phone Runtime Component 項目 WPRuntimeComponent.WindowsPhoneRuntimeComponent component = new WPRuntimeComponent.WindowsPhoneRuntimeComponent(); // 調用 Windows Phone Runtime Component(C++) 中的函數 lblMsg.Text = "調用 Windows Phone Runtime Component 中的函數:" + component.Add(10, 10).ToString(); lblMsg.Text += Environment.NewLine; // 調用 DLL(C++) 中的函數,方式:Windows Phone Runtime Component(C++) 作為一個代理調用 DLL(C++),然后 C# 調用 Windows Phone Runtime Component(C++) lblMsg.Text += "調用 Windows Phone Runtime Component 中的函數(其僅作為一個代理,實際調用的是 PhoneDLL 中的函數):" + component.Add2(10, 10).ToString(); base.OnNavigatedTo(e); } } }
二、演示如何在 C# 中調用 Windows Phone Runtime Component(C++ & D3D),從而獲取屏幕的分辨率
1、WPRuntimeComponent 項目
Helper.h
/* * 注意: * 由於需要 D3D,所以需要在 項目屬性 -> 配置屬性 -> 鏈接器 -> 輸入 -> 附加依賴項 中增加“d3d11.lib” * * 參考: * http://blogs.microsoft.co.il/blogs/tomershamam/archive/2012/07/24/get-screen-resolution-in-windows-8-metro-style-application.aspx */ #pragma once #include <wrl/client.h> #include <d3d11_1.h> namespace DX { inline void ThrowIfFailed(HRESULT hr) { if (FAILED(hr)) { // 拋出 DirectX API 的錯誤 throw Platform::Exception::CreateException(hr); } } } namespace WPRuntimeComponent { public ref class Helper sealed { public: Helper(); // 一個屬性,用於得到屏幕分辨率 property Windows::Foundation::Point ScreenResolution { Windows::Foundation::Point get(); } private: D3D_FEATURE_LEVEL m_featureLevel; Microsoft::WRL::ComPtr<ID3D11Device1> m_d3dDevice; }; }
Helper.cpp
/* * 注意: * 由於需要 D3D,所以需要在 項目屬性 -> 配置屬性 -> 鏈接器 -> 輸入 -> 附加依賴項 中增加“d3d11.lib” * * 參考: * http://blogs.microsoft.co.il/blogs/tomershamam/archive/2012/07/24/get-screen-resolution-in-windows-8-metro-style-application.aspx */ #include "pch.h" #include "Helper.h" #include <agile.h> using namespace Microsoft::WRL; using namespace Windows::Foundation; using namespace WPRuntimeComponent; using namespace Platform; Helper::Helper() { UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; #if defined(_DEBUG) creationFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; ComPtr<ID3D11Device> device; ComPtr<ID3D11DeviceContext> context; DX::ThrowIfFailed( D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &m_featureLevel, &context ) ); DX::ThrowIfFailed(device.As(&m_d3dDevice)); } // 獲取屏幕分辨率 Point Helper::ScreenResolution::get() { ComPtr<IDXGIDevice> dxgiDevice; DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice)); ComPtr<IDXGIAdapter> dxgiAdapter; DX::ThrowIfFailed(dxgiDevice->GetAdapter(&dxgiAdapter)); IDXGIOutput * pOutput; if (dxgiAdapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { DXGI_OUTPUT_DESC desc; pOutput->GetDesc(&desc); return Point(desc.DesktopCoordinates.right, desc.DesktopCoordinates.bottom); } return Point(0, 0); }
2、調用者
CPP/GetResolution.xaml
<phone:PhoneApplicationPage x:Class="Demo.CPP.GetResolution" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <Grid Background="Transparent"> <StackPanel> <TextBlock x:Name="lblMsg" TextWrapping="Wrap" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
CPP/GetResolution.xaml.cs
/* * 演示如何在 C# 中調用 Windows Phone Runtime Component(C++ & D3D),從而獲取屏幕的分辨率 * * * 注: * 用於獲取屏幕分辨率的 Windows Phone Runtime Component(C++ & D3D) 項目參見:WPRuntimeComponent 項目 */ using System.Windows.Navigation; using Microsoft.Phone.Controls; using Windows.Foundation; namespace Demo.CPP { public partial class GetResolution : PhoneApplicationPage { public GetResolution() { InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { // 引用 C++ 項目,實例化 Helper 類 WPRuntimeComponent.Helper helper = new WPRuntimeComponent.Helper(); // 調用 Helper 中的屬性,得到屏幕分辨率 Point screenResolution = helper.ScreenResolution; // 顯示分辨率 lblMsg.Text = string.Format("分辨率:{0}×{1}", screenResolution.X.ToString(), screenResolution.Y.ToString()); base.OnNavigatedTo(e); } } }
OK
[源碼下載]