Walkthrough: Create an SDK using C++

Applies to: yesVisual Studio noVisual Studio for Mac

Note

This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here

This walkthrough shows how to create a native C++ math library SDK, package the SDK as a Visual Studio Extension (VSIX), and then use it to create an app. The walkthrough is divided into these steps:

Prerequisites

To follow this walkthrough, you must install the Visual Studio SDK. For more information, see Visual Studio SDK.

To create the native and Windows Runtime libraries

  1. On the menu bar, choose File > New > Project.

  2. In the list of templates, expand Visual C++ > Windows Universal, and then select the DLL (Windows Universal apps) template. In the Name box, specify NativeMath, and then choose the OK button.

  3. Update NativeMath.h to match the following code.

    #pragma once
    
    class __declspec(dllexport) BasicMath 
    {
    public:
        BasicMath();
        double add(double firstNumber, double secondNumber);
        double subtract(double firstNumber, double secondNumber);
    };
    
  4. Update NativeMath.cpp to match this code:

    // 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. In Solution Explorer, open the shortcut menu for Solution 'NativeMath', and then choose Add > New Project.

  6. In the list of templates, expand Visual C++, and then select the Windows Runtime Component template. In the Name box, specify NativeMathWRT, and then choose the OK button.

  7. Update Class1.h to match this code:

    #pragma once
    
    namespace NativeMathWRT
    {
        public ref class BasicMathWinMD sealed
        {
        public:
            BasicMathWinMD(){};
            double multiply(double firstNumber, double secondNumber);
            double divide(double firstNumber, double secondNumber);
        };
    }
    
  8. Update Class1.cpp to match this code:

    // 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. On the menu bar, choose Build > Build Solution.

To create the NativeMathVSIX extension project

  1. In Solution Explorer, open the shortcut menu for Solution 'NativeMath', and then choose Add > New Project.

  2. In the list of templates, expand Visual C# > Extensibility, and then select VSIX Project. In the Name box, specify NativeMathVSIX, and then choose the OK button.

  3. In Solution Explorer, open the shortcut menu for source.extension.vsixmanifest, and then choose View Code.

  4. Use the following XML to replace the existing 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. In Solution Explorer, open the shortcut menu for the NativeMathVSIX project, and then choose Add > New Item.

  6. In the list of Visual C# Items, expand Data, and then select XML File. In the Name box, specify SDKManifest.xml, and then choose the OK button.

  7. Use this XML to replace the contents of the file:

    <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. In Solution Explorer, under the NativeMathVSIX project, create this folder structure:

    \DesignTime
          \CommonConfiguration
                \Neutral
                      \Include
          \Debug
                \x86
    \Redist
          \Debug
                \x86
    \References
          \CommonConfiguration
                \Neutral
    
  9. In Solution Explorer, open the shortcut menu for Solution 'NativeMath', and then choose Open Folder in File Explorer.

  10. In File Explorer, copy $SolutionRoot$\NativeMath\NativeMath.h, and then in Solution Explorer, under the NativeMathVSIX project, paste it in the $SolutionRoot$\NativeMathVSIX\DesignTime\CommonConfiguration\Neutral\Include\ folder.

    Copy $SolutionRoot$\Debug\NativeMath\NativeMath.lib, and then paste it in the $SolutionRoot$\NativeMathVSIX\DesignTime\Debug\x86\ folder.

    Copy $SolutionRoot$\Debug\NativeMath\NativeMath.dll and paste it in the $SolutionRoot$\NativeMathVSIX\Redist\Debug\x86\ folder.

    Copy $SolutionRoot$\Debug\NativeMathWRT\NativeMathWRT.dll and paste it in the $SolutionRoot$\NativeMathVSIX\Redist\Debug\x86 folder. Copy $SolutionRoot$\Debug\NativeMathWRT\NativeMathWRT.winmd and paste it in the $SolutionRoot$\NativeMathVSIX\References\CommonConfiguration\Neutral folder.

    Copy $SolutionRoot$\Debug\NativeMathWRT\NativeMathWRT.pri and paste it in the $SolutionRoot$\NativeMathVSIX\References\CommonConfiguration\Neutral folder.

  11. In the $SolutionRoot$\NativeMathVSIX\DesignTime\Debug\x86\ folder, create a text file that's named NativeMathSDK.props, and then paste the following contents in it:

    <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. On the menu bar, choose View > Other Windows > Properties Window (Keyboard: Choose the F4 key).

  13. In Solution Explorer, select the NativeMathWRT.winmd file. In the Properties window, change the Build Action property to Content, and then change the Include in VSIX property to True.

    Repeat this process for the NativeMath.h file.

    Repeat this process for the NativeMathWRT.pri file.

    Repeat this process for the NativeMath.Lib file.

    Repeat this process for the NativeMathSDK.props file.

  14. In Solution Explorer, select the NativeMath.h file. In the Properties window, change the Include in VSIX property to True.

    Repeat this process for the NativeMath.dll file.

    Repeat this process for the NativeMathWRT.dll file.

    Repeat this process for the SDKManifest.xml file.

  15. On the menu bar, choose Build > Build Solution.

  16. In Solution Explorer, open the shortcut menu for the NativeMathVSIX project, and then choose Open Folder in File Explorer.

  17. In File Explorer, navigate to the $SolutionRoot$\NativeMathVSIX\bin\Debug folder, and then run NativeMathVSIX.vsix to begin the installation.

  18. Choose the Install button, wait for the installation to finish, and then open Visual Studio.

To create a sample app that uses the class library

  1. On the menu bar, choose File > New > Project.

  2. In the list of templates, expand Visual C++ > Windows Universal and then select Blank App. In the Name box, specify NativeMathSDKSample, and then choose the OK button.

  3. In Solution Explorer, open the shortcut menu for the NativeMathSDKSample project, and then choose Add > Reference.

  4. In the Add Reference dialog box, in the list of reference types, expand Universal Windows, and then select Extensions. Finally, Select the Native Math SDK check box, and then choose the OK button.

  5. Display the project properties for NativeMathSDKSample.

    The properties that you defined in NativeMathSDK.props were applied when you added the reference. You can verify the properties were applied by examining the VC++ Directories property of the project's Configuration Properties.

  6. In Solution Explorer, open MainPage.xaml, and then use the following XAML to replace its content:

    <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. Update Mainpage.xaml.h to match this code:

    //
    // 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. Update MainPage.xaml.cpp to match this code:

    //
    // 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. Choose the F5 key to run the app.

  10. In the app, enter any two numbers, select an operation, and then choose the = button.

    The correct result appears.

    This walkthrough showed how to create and use an Extension SDK to call into a Windows Runtime library and a non-Windows Runtime library.

Next steps

See also