チュートリアル: C++ を使用して SDK を作成する

このチュートリアルでは、ネイティブ C++ 数値演算ライブラリ SDK を作成し、SDK を Visual Studio 拡張機能 (VSIX) としてパッケージ化して、それを使用してアプリを作成する方法について説明します。 このチュートリアルは、次のステップに分かれています。

前提条件

このチュートリアルを行うには、Visual Studio SDK をインストールする必要があります。 詳細については、「Visual Studio SDK」を参照してください。

ネイティブ ライブラリと Windows ランタイム ライブラリを作成するには

  1. メニュー バーで、 [ファイル]>[新規作成]>[プロジェクト] を選択します。

  2. テンプレートの一覧で [Visual C++]>[Windows ユニバーサル] を展開し、[DLL (Windows ユニバーサル アプリ)] テンプレートを選択します。 [名前] ボックスで「NativeMath」と指定してから、[OK] ボタンを選択します。

  3. 次のコードに一致するように NativeMath.h を更新します。

    #pragma once
    
    class __declspec(dllexport) BasicMath 
    {
    public:
        BasicMath();
        double add(double firstNumber, double secondNumber);
        double subtract(double firstNumber, double secondNumber);
    };
    
  4. 次のコードに一致するように NativeMath.cpp を更新します。

    // NativeMath.cpp : Defines the exported functions for the DLL application.
    //
    
    #include "pch.h"
    #include "NativeMath.h"
    
    
    BasicMath::BasicMath()
    {
    }
    
    double BasicMath::add(double firstNumber, double secondNumber)
    {
        return firstNumber + secondNumber;
    }
    
    double BasicMath::subtract(double firstNumber, double secondNumber)
    {
        return firstNumber - secondNumber;
    }
    
  5. ソリューション エクスプローラーで、['NativeMath' ソリューション] のショートカット メニューを開き、[追加]>[新しいプロジェクト] の順に選択します。

  6. テンプレートの一覧で [Visual C++] を展開し、[Windows ランタイム コンポーネント] テンプレートを選択します。 [名前] ボックスで「NativeMathWRT」と指定してから、[OK] ボタンを選択します。

  7. 次のコードに一致するように Class1.h を更新します。

    #pragma once
    
    namespace NativeMathWRT
    {
        public ref class BasicMathWinMD sealed
        {
        public:
            BasicMathWinMD(){};
            double multiply(double firstNumber, double secondNumber);
            double divide(double firstNumber, double secondNumber);
        };
    }
    
  8. 次のコードに一致するように Class1.cpp を更新します。

    // Class1.cpp
    #include "pch.h"
    #include "Class1.h"
    
    using namespace NativeMathWRT;
    using namespace Platform;
        
    double BasicMathWinMD::multiply(double firstNumber, double secondNumber)
    {
        return firstNumber * secondNumber;
    }
    
    double BasicMathWinMD::divide(double firstNumber, double secondNumber)
    {
        if(0 == secondNumber) 
            return -1;
    
        return firstNumber / secondNumber;
    }
    
  9. メニュー バーで、 [ビルド]>[ソリューションのビルド] の順にクリックします。

NativeMathVSIX 拡張機能プロジェクトを作成するには

  1. ソリューション エクスプローラーで、['NativeMath' ソリューション] のショートカット メニューを開き、[追加]>[新しいプロジェクト] の順に選択します。

  2. テンプレートの一覧で、[Visual C#]>[機能拡張] を展開し、[VSIX プロジェクト] を選択します。 [名前] ボックスで「NativeMathVSIX」と指定してから、[OK] ボタンを選択します。

  3. ソリューション エクスプローラーで、source.extension.vsixmanifest ファイルのショートカット メニューを開き、[コードの表示] を選択します。

  4. 次の XML で既存の XML を置き換えます。

    <PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
      <Metadata>
        <Identity Id="NativeMathVSIX..c6b3cae1-e7e2-4e71-90f6-21017ea0dff7" Version="1.0" Language="en-US" Publisher="MyName" />
        <DisplayName>Native Math SDK</DisplayName>
        <Description>Native Math Library w/ Windows Runtime Additions</Description>
      </Metadata>
      <Installation Scope="Global" AllUsers="true">
        <InstallationTarget Id="Microsoft.ExtensionSDK" TargetPlatformIdentifier="Windows" TargetPlatformVersion="v8.0" SdkName="NativeMathSDK" SdkVersion="1.0" />
      </Installation>
      <Dependencies>
      </Dependencies>
      <Assets>
        <Asset Type="Microsoft.ExtensionSDK" d:Source="File" Path="SDKManifest.xml" />
      </Assets>
    </PackageManifest>
    
  5. ソリューション エクスプローラーで、NativeMathVSIX プロジェクトのショートカット メニューを開き、[追加]>[新しい項目] を選択します。

  6. Visual C# の項目の一覧で、[データ] を展開し、[XML ファイル] を選択します。 [名前] ボックスで「SDKManifest.xml」と指定してから、[OK] ボタンを選択します。

  7. 次の XML を使用してファイルの内容を置き換えます。

    <FileList
      Identity = "NativeMathSDK, Version=1.0"
      DisplayName = "Native Math SDK"
      MinVSVersion = "11.0"
      AppliesTo = "WindowsAppContainer + (CSharp | VB | VisualC)">
      <File Reference="NativeMathWRT.winmd" Implementation="NativeMathWRT.dll" />
    </FileList>
    
  8. ソリューション エクスプローラーNativeMathVSIX プロジェクトで、次のフォルダー構造を作成します。

    \DesignTime
          \CommonConfiguration
                \Neutral
                      \Include
          \Debug
                \x86
    \Redist
          \Debug
                \x86
    \References
          \CommonConfiguration
                \Neutral
    
  9. ソリューション エクスプローラー['NativeMath' ソリューション] ショートカット メニューを開いてから、[エクスプローラーでフォルダーを開く] を選択します。

  10. エクスプローラー$SolutionRoot$\NativeMath\NativeMath.h をコピーし、ソリューション エクスプローラーで、NativeMathVSIX プロジェクトの下の $SolutionRoot$\NativeMathVSIX\DesignTime\CommonConfiguration\Neutral\Include\ フォルダーに貼り付けます。

    $SolutionRoot$\Debug\NativeMath\NativeMath.lib をコピーし、$SolutionRoot$\NativeMathVSIX\DesignTime\Debug\x86\ フォルダーに貼り付けます。

    $SolutionRoot$\Debug\NativeMath\NativeMath.dll をコピーし、$SolutionRoot$\NativeMathVSIX\Redist\Debug\x86\ フォルダーに貼り付けます。

    $SolutionRoot$\Debug\NativeMathWRT\NativeMathWRT.dll をコピーし、$SolutionRoot$\NativeMathVSIX\Redist\Debug\x86 フォルダーに貼り付けます。 $SolutionRoot$\Debug\NativeMathWRT\NativeMathWRT.winmd をコピーし、$SolutionRoot$\NativeMathVSIX\References\CommonConfiguration\Neutral フォルダーに貼り付けます。

    $SolutionRoot$\Debug\NativeMathWRT\NativeMathWRT.pri をコピーし、$SolutionRoot$\NativeMathVSIX\References\CommonConfiguration\Neutral フォルダーに貼り付けます。

  11. $SolutionRoot$\NativeMathVSIX\DesignTime\Debug\x86\ フォルダーに、NativeMathSDK.props という名前のテキスト ファイルを作成し、次の内容を貼り付けます。

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <NativeMathSDKPath>$(FrameworkSDKRoot)\..\..\UAP\v0.8.0.0\ExtensionSDKs\NativeMathSDK\1.0\</NativeMathSDKPath>
        <IncludePath>$(NativeMathSDKPath)DesignTime\CommonConfiguration\Neutral\Include;$(IncludePath)</IncludePath>
        <LibraryPath>$(NativeMathSDKPath)DesignTime\Debug\x86;$(LibraryPath)</LibraryPath>
      </PropertyGroup>
      <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
         <Link>
           <AdditionalDependencies>NativeMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
         </Link>
      </ItemDefinitionGroup>
    </Project>
    
  12. メニューバーで、[表示]>[他のウィンドウ]>[プロパティウィンドウ] を選択します (キーボード: F4 キーを押します)。

  13. ソリューション エクスプローラーで、NativeMathWRT.winmd ファイルを選択します。 [プロパティ] ウィンドウで、[ビルド アクション] プロパティを [コンテンツ] に変更してから、[VSIX に含める] プロパティを [True] に変更します。

    NativeMath.h ファイルに対してこのプロセスを繰り返します。

    NativeMathWRT.pri ファイルに対してこのプロセスを繰り返します。

    NativeMath.Lib ファイルに対してこのプロセスを繰り返します。

    NativeMathSDK.props ファイルに対してこのプロセスを繰り返します。

  14. ソリューション エクスプローラーで、NativeMath.h ファイルを選択します。 [プロパティ] ウィンドウで、[VSIX に含める] プロパティを [True] に変更します。

    NativeMath.dll ファイルに対してこのプロセスを繰り返します。

    NativeMathWRT.dll ファイルに対してこのプロセスを繰り返します。

    SDKManifest.xml ファイルに対してこのプロセスを繰り返します。

  15. メニュー バーで、 [ビルド]>[ソリューションのビルド] の順にクリックします。

  16. ソリューション エクスプローラー[NativeMathVSIX] プロジェクトのショートカット メニューを開いてから、[エクスプローラーでフォルダーを開く] を選択します。

  17. エクスプローラーで、$SolutionRoot$\NativeMathVSIX\bin\Debug フォルダーに移動し、次に NativeMathVSIX.vsix を実行してインストールを開始します。

  18. [インストール] ボタンをクリックし、インストールが完了するのを待ちます。次に、Visual Studio を開きます。

クラス ライブラリを使用するサンプル アプリを作成するには

  1. メニュー バーで、 [ファイル]>[新規作成]>[プロジェクト] を選択します。

  2. テンプレートの一覧で、[Visual C++]>[Windows ユニバーサル] を展開し、[空のアプリ] を選択します。 [名前] ボックスで「NativeMathSDKSample」と指定してから、[OK] ボタンを選択します。

  3. ソリューション エクスプローラーで、NativeMathSDKSample プロジェクトのショートカット メニューを開いて、[追加]>[参照] を選択します。

  4. [参照の追加] ダイアログ ボックスの [参照の種類] の一覧で、[ユニバーサル Windows] を展開し、[拡張機能] を選択します。 最後に、[Native Math SDK] チェック ボックスをオンにし、[OK] をクリックします。

  5. NativeMathSDKSample のプロジェクト プロパティを表示します。

    参照を追加したときに、NativeMathSDK.props に定義したプロパティが適用されました。 プロジェクトの [構成プロパティ][VC++ ディレクトリ] プロパティを調べることで、プロパティが適用されたことを確認できます。

  6. ソリューション エクスプローラー[MainPage.xaml] を開き、次の XAML を使用して内容を置き換えます。

    <Page
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:NativeMathSDKSample"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        x:Class="NativeMathSDKSample.MainPage"
        IsTabStop="false"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <TextBox x:Name="FirstNumber" HorizontalAlignment="Left" Margin="327,123,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Height="84" Width="259" FontSize="48"/>
            <TextBox x:Name="SecondNumber" HorizontalAlignment="Left" Margin="687,123,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Height="84" Width="271" FontSize="48"/>
            <Button x:Name="Execute" Content="=" HorizontalAlignment="Left" Margin="478,387,0,0" VerticalAlignment="Top" Height="63" Width="332" Click="Execute_Click"/>
            <RadioButton Name="add" Content="Add" HorizontalAlignment="Left" Margin="273,262,0,0" VerticalAlignment="Top" GroupName="Operation" IsChecked="True"/>
            <RadioButton Name="subtract" Content="Subtract" HorizontalAlignment="Left" Margin="453,262,0,0" VerticalAlignment="Top" GroupName="Operation" IsChecked="False"/>
            <RadioButton Name="multiplyWRT" Content="Multiply(WRT)" HorizontalAlignment="Left" Margin="615,262,0,0" VerticalAlignment="Top" GroupName="Operation" IsChecked="False"/>
            <RadioButton Name="divideWRT" Content="Divide(WRT)" HorizontalAlignment="Left" Margin="891,262,0,0" VerticalAlignment="Top" GroupName="Operation" IsChecked="False"/>
            <TextBlock Name="resultText" HorizontalAlignment="Left" Margin="478,525,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="332" Height="70" FontSize="48"/>
        </Grid>
    </Page>
    
  7. 次のコードに一致するように Mainpage.xaml.h を更新します。

    //
    // MainPage.xaml.h
    // Declaration of the MainPage class.
    //
    
    #pragma once
    
    #include "MainPage.g.h"
    
    namespace NativeMathSDKSample
    {
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public ref class MainPage sealed
        {
        public:
            MainPage();
    
        protected:
            virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
            virtual void Execute_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
        };
    }
    
  8. 次のコードに一致するように MainPage.xaml.cpp を更新します。

    //
    // MainPage.xaml.cpp
    // Implementation of the MainPage class.
    //
    
    #include "pch.h"
    #include "MainPage.xaml.h"
    
    #include <sstream>
    
    #include "NativeMath.h"
    
    using namespace NativeMathSDKSample;
    
    using namespace Platform;
    using namespace Windows::Foundation;
    using namespace Windows::Foundation::Collections;
    using namespace Windows::UI::Xaml;
    using namespace Windows::UI::Xaml::Controls;
    using namespace Windows::UI::Xaml::Controls::Primitives;
    using namespace Windows::UI::Xaml::Data;
    using namespace Windows::UI::Xaml::Input;
    using namespace Windows::UI::Xaml::Media;
    using namespace Windows::UI::Xaml::Navigation;
    
    using namespace NativeMathWRT;
    
    // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
    
    MainPage::MainPage()
    {
        InitializeComponent();
    }
    
    /// <summary>
    /// Invoked when this page is about to be displayed in a Frame.
    /// </summary>
    /// <param name="e">Event data that describes how this page was reached.  The Parameter
    /// property is typically used to configure the page.</param>
    void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
    {
    }
    
    void NativeMathSDKSample::MainPage::Execute_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
        double iFirstNumber = _wtof(FirstNumber->Text->Data());
        double iSecondNumber = _wtof(SecondNumber->Text->Data());
        double result = 0;
    
        BasicMathWinMD^ basicMathWinMD = ref new BasicMathWinMD();
        BasicMath basicMath;
    
        if(add->IsChecked->Value == true)
        {
            result = basicMath.add(iFirstNumber, iSecondNumber);
        }
        else if(subtract->IsChecked->Value == true)
        {
            result = basicMath.subtract(iFirstNumber, iSecondNumber);
        }
        else if(multiplyWRT->IsChecked->Value == true)
        {
            result = basicMathWinMD->multiply(iFirstNumber, iSecondNumber);
        }
        else if (divideWRT->IsChecked->Value == true)
        {
            result = basicMathWinMD->divide(iFirstNumber, iSecondNumber);
        }
    
        std::wstringstream s;
        s << result;
    
        resultText->Text = ref new String(s.str().c_str());
    
    }
    
  9. F5 キーを押してアプリを実行します。

  10. アプリで、任意の 2 つの数値を入力し、操作を選択して、= ボタンを選択します。

    正しい結果が表示されます。

    このチュートリアルでは、拡張 SDK を作成して使用し、Windows ランタイム ライブラリと Windows ランタイム以外のライブラリを呼び出す方法について説明しました。