이 연습에서는 네이티브 C++ 수학 라이브러리 SDK를 만들고 SDK를 VSIX(Visual Studio Extension)로 패키지한 다음, 이것을 사용하여 앱을 만드는 방법을 보여줍니다. 연습은 다음 단계로 나뉩니다.
필수 조건
이 연습을 수행하려면 Visual Studio SDK를 설치해야 합니다. 자세한 내용은 Visual Studio SDK를 참조하세요.
네이티브 및 Windows 런타임 라이브러리 만들기
메뉴 모음에서 파일>새로 만들기>프로젝트를 선택합니다.
템플릿 목록에서 Visual C++>Windows 유니버설을 확장한 다음, DLL(Windows 유니버설 앱) 템플릿을 선택합니다. 이름 상자에
NativeMath
를 지정한 다음, 확인 단추를 선택합니다.다음 코드와 일치하도록 NativeMath.h를 업데이트합니다.
#pragma once class __declspec(dllexport) BasicMath { public: BasicMath(); double add(double firstNumber, double secondNumber); double subtract(double firstNumber, double secondNumber); };
다음 코드와 일치하도록 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; }
솔루션 탐색기에서 솔루션 'NativeMath'의 바로가기 메뉴를 연 다음, 추가>새 프로젝트를 선택합니다.
템플릿 목록에서 Visual C++를 확장한 다음, Windows 런타임 구성 요소 템플릿을 선택합니다. 이름 상자에
NativeMathWRT
를 지정한 다음, 확인 단추를 선택합니다.다음 코드와 일치하도록 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); }; }
다음 코드와 일치하도록 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; }
메뉴 모음에서 빌드>솔루션 빌드를 선택합니다.
NativeMathVSIX 확장 프로젝트 만들기
솔루션 탐색기에서 솔루션 'NativeMath'의 바로가기 메뉴를 연 다음, 추가>새 프로젝트를 선택합니다.
템플릿 목록에서 Visual C#>확장성을 확장한 다음, VSIX 프로젝트를 선택합니다. 이름 상자에 NativeMathVSIX를 지정한 다음, 확인 단추를 선택합니다.
솔루션 탐색기에서 source.extension.vsixmanifest에 대한 바로 가기 메뉴를 연 다음, 코드 보기를 선택합니다.
다음 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>
솔루션 탐색기에서 NativeMathVSIX 프로젝트의 바로 가기 메뉴를 연 다음, 추가>새 항목을 선택합니다.
Visual C# 항목 목록에서 데이터를 확장한 다음, XML 파일을 선택합니다. 이름 상자에
SDKManifest.xml
를 지정한 다음, 확인 단추를 선택합니다.이 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>
솔루션 탐색기의 NativeMathVSIX 프로젝트에서 다음 폴더 구조를 만듭니다.
\DesignTime \CommonConfiguration \Neutral \Include \Debug \x86 \Redist \Debug \x86 \References \CommonConfiguration \Neutral
솔루션 탐색기에서 솔루션 'NativeMath'의 바로 가기 메뉴를 연 다음, 파일 탐색기에서 폴더 열기를 선택합니다.
파일 탐색기에서 $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 폴더에 붙여넣습니다.
$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>
메뉴 모음에서 보기>다른 창>속성 창을 선택합니다(키보드: F4 키 선택).
솔루션 탐색기에서 NativeMathWRT.winmd 파일을 선택합니다. 속성 창에서 빌드 작업 속성을 콘텐츠로 변경한 다음, VSIX에 포함 속성을 True로 변경합니다.
NativeMath.h 파일에 대해 이 프로세스를 반복합니다.
NativeMathWRT.pri 파일에 대해 이 프로세스를 반복합니다.
NativeMath.Lib 파일에 대해 이 프로세스를 반복합니다.
NativeMathSDK.props 파일에 대해 이 프로세스를 반복합니다.
솔루션 탐색기에서 NativeMath.h 파일을 선택합니다. 속성 창에서 VSIX에 포함 속성을 True로 변경합니다.
NativeMath.dll 파일에 대해 이 프로세스를 반복합니다.
NativeMathWRT.dll 파일에 대해 이 프로세스를 반복합니다.
SDKManifest.xml 파일에 대해 이 프로세스를 반복합니다.
메뉴 모음에서 빌드>솔루션 빌드를 선택합니다.
솔루션 탐색기에서 NativeMathVSIX 프로젝트의 바로 가기 메뉴를 연 다음, 파일 탐색기에서 폴더 열기를 선택합니다.
파일 탐색기에서 $SolutionRoot$\NativeMathVSIX\bin\Debug 폴더로 이동한 다음, NativeMathVSIX.vsix를 실행하여 설치를 시작합니다.
설치 단추를 선택하고 설치가 완료되기를 기다린 다음, Visual Studio를 엽니다.
클래스 라이브러리를 사용하는 샘플 앱을 만들려면
메뉴 모음에서 파일>새로 만들기>프로젝트를 선택합니다.
템플릿 목록에서 Visual C++>Windows 유니버설을 확장한 다음, 빈 앱을 선택합니다. 이름 상자에 NativeMathSDKSample을 지정한 다음, 확인 단추를 선택합니다.
솔루션 탐색기에서 NativeMathSDKSample 프로젝트의 바로 가기 메뉴를 연 다음, 추가>참조를 선택합니다.
참조 추가 대화 상자의 참조 형식 목록에서 유니버설 Windows를 확장한 다음, 확장을 선택합니다. 마지막으로 Native Math SDK 확인란을 선택한 다음, 확인 단추를 선택합니다.
NativeMathSDKSample의 프로젝트 속성을 표시합니다.
NativeMathSDK.props에서 정의한 속성은 참조를 추가할 때 적용되었습니다. 프로젝트 구성 속성의 VC++ 디렉터리 속성을 검사하여 속성이 적용되었는지 확인할 수 있습니다.
솔루션 탐색기에서 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>
다음 코드와 일치하도록 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); }; }
다음 코드와 일치하도록 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()); }
F5 키를 선택하여 앱을 실행합니다.
앱에서 두 개의 숫자를 입력하고 작업을 선택한 다음, = 단추를 선택합니다.
올바른 결과가 나타납니다.
이 연습에서는 확장 SDK를 만들고 사용하여 Windows 런타임 라이브러리 및 비 Windows 런타임 라이브러리를 호출하는 방법을 보여주었습니다.