首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 8 Store Apps C# 呼叫 C++ 元件完整實作:WinRT Component 代理 DLL 與 D3D 取得螢幕解析度

     編輯:關於.NET

架構概覽

C# 無法直接呼叫 Native C++ DLL,需透過 Windows Runtime Component (C++/CX) 做為橋接層:

C# App → WinRT Component (C++/CX) → Native DLL (C++)

案例一:WinRT Component 代理 Native DLL

1. Native DLL 專案

// WindowsDll.h
#pragma once
extern "C" _declspec(dllexport) int Add(int x, int y);

// WindowsDll.cpp
#include "pch.h"
#include "WindowsDll.h"
#include 
#define WINAPI_FAMILY WINAPI_PARTITION_APP  // 必須:宣告為 App 容器相容
int Add(int x, int y) { return x + y; }

2. WinRT Component 專案

// MyRuntimeComponent.h
#pragma once
#include 
namespace WindowsRuntimeComponent
{
    public ref class MyRuntimeComponent sealed
    {
    public:
        int Add(int x, int y);                    // 直接實作
        int Add2(int i, int j);                   // 代理呼叫 Native DLL
    };
}

// MyRuntimeComponent.cpp
#include "pch.h"
#include "MyRuntimeComponent.h"
using namespace WindowsRuntimeComponent;

int MyRuntimeComponent::Add(int x, int y) { return x + y; }

int MyRuntimeComponent::Add2(int i, int j)
{
    typedef int(*MyAdd)(int, int);
    HINSTANCE hDll = LoadPackagedLibrary(L"CPP/WindowsDLL.dll", 0); // 相對路徑
    MyAdd add = (MyAdd)GetProcAddress(hDll, "Add");
    int result = add(i, j);
    FreeLibrary(hDll);
    return result;
}

3. C# 消費端呼叫

var component = new WindowsRuntimeComponent.MyRuntimeComponent();
// 直接呼叫
lblMsg.Text = "直接呼叫: " + component.Add(10, 10);
// 代理呼叫 Native DLL
lblMsg.Text += "\n代理呼叫: " + component.Add2(10, 10);

案例二:C++/CX + D3D 取得螢幕解析度

WinRT Component 專案 (需連結 d3d11.lib)

// Helper.h
#pragma once
#include 
#include 
namespace WindowsRuntimeComponent
{
    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
#include "pch.h"
#include "Helper.h"
#include 
#include 
using namespace Microsoft::WRL;
using namespace Windows::Foundation;
using namespace WindowsRuntimeComponent;

Helper::Helper()
{
    UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#if _DEBUG
    flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
    D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, /* ... */ };
    ComPtr<ID3D11Device> device;
    ComPtr<ID3D11DeviceContext> context;
    DX::ThrowIfFailed(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, flags, levels, ARRAYSIZE(levels), D3D11_SDK_VERSION, &device, &m_featureLevel, &context));
    DX::ThrowIfFailed(device.As(&m_d3dDevice));
}

Windows::Foundation::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);
}

C# 呼叫

var helper = new WindowsRuntimeComponent.Helper();
Point res = helper.ScreenResolution;
lblMsg.Text = string.Format("解析度: {0}x{1}", res.X, res.Y);

部署注意事項

  • Native DLL 需置於 Appx 套件內 (專案根目錄),並設定「複製到輸出目錄」。
  • WinRT Component 專案輸出為 .winmd,C# 專案加入參考即可使用。
  • D3D 建立裝置需指定 D3D11_CREATE_DEVICE_BGRA_SUPPORT 以支援 XAML 互操作。

總結

WinRT Component 是 C# 呼叫 Native C++ 的標準橋樑,適用於效能關鍵路徑、既有 C++ 資產重用、硬體加速 (D3D) 等場景。掌握 LoadPackagedLibrary、ComPtr、WRL 等關鍵技術,即可構建高效能混合語言應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved