C++/WinRT 문제 해결Troubleshooting C++/WinRT issues

참고

프로젝트 템플릿 지원을 제공하는 C++/WinRT VSIX(Visual Studio Extension)를 설치 및 사용하는 방법에 대한 자세한 내용은 Visual Studio의 C++/WinRT 지원을 참조하세요.For info about installing and using the C++/WinRT Visual Studio Extension (VSIX) (which provides project template support) see Visual Studio support for C++/WinRT.

이 항목은 당장 필요하지 않더라도 바로 파악할 수 있도록 사전 정보로 제공되었습니다.This topic is up front so that you're aware of it right away; even if you don't need it yet. 아래 문제 해결 표의 증상과 해결 방법은 새 코드를 잘라내든, 기존 앱을 포팅하든 간에 유용할 수 있습니다.The table of troubleshooting symptoms and remedies below may be helpful to you whether you're cutting new code or porting an existing app. 포팅 중이며 프로젝트를 빌드 및 실행하는 단계까지 빠르게 도달하려는 경우 문제가 발생하는, 중요하지 않은 코드를 주석으로 처리하거나 스텁한 후 나중에 돌아가서 문제를 해결하면 일시적으로 진행할 수 있습니다.If you're porting, and you're eager to forge ahead and get to the stage where your project builds and runs, then you can make temporary progress by commenting or stubbing out any non-essential code that's causing issues, and then returning to pay off that debt later.

자주 묻는 질문 목록은 자주 묻는 질문을 참조하세요.For a list of frequently-asked questions, see Frequently-asked questions.

XAML 문제 추적Tracking down XAML issues

예외 내에 의미 있는 오류 메시지가 없는 경우 특히, XAML 구문 분석 예외를 진단하기 어려울 수 있습니다.XAML parse exceptions can be difficult to diagnose—particularly if there are no meaningful error messages within the exception. 초기에 구문 분석 예외를 찾기 위해 첫째 예외를 catch하도록 디버거가 구성되어 있는지 확인하세요.Make sure that the debugger is configured to catch first-chance exceptions (to try and catch the parsing exception early on). 디버거에서 예외 변수를 검사하여 HRESULT 또는 메시지에 유용한 정보가 있는지 확인할 수 있습니다.You may be able to inspect the exception variable in the debugger to determine whether the HRESULT or message has any useful information. XAML 파서로 오류 메시지 출력을 위한 Visual Studio 출력 창을 확인할 수도 있습니다.Also, check Visual Studio's output window for error messages output by the XAML parser.

앱이 종료되고 XAML 태그 구문 분석 중 처리되지 않은 예외가 throw되었다는 것만 알 수 있는 경우 누락된 리소스를 키로 참조한 결과일 수 있습니다.If your app terminates and all you know is that an unhandled exception was thrown during XAML markup parsing, then that could be the result of a reference (by key) to a missing resource. 또는 UserControl, 사용자 지정 컨트롤 또는 사용자 지정 레이아웃 패널 내에서 예외가 throw되었을 수 있습니다.Or, it could be an exception thrown inside a UserControl, a custom control, or a custom layout panel. 마지막으로 사용할 수 있는 방법은 이진 분할입니다.A last resort is a binary split. XAML 페이지에서 태그의 절반 정도를 제거하고 앱을 다시 실행합니다.Remove about half of the markup from a XAML Page and re-run the app. 그러면 오류가 제거한 절반(어떤 경우든지 지금 복원해야 함)에서 발생했는지, 제거하지 않은 절반에서 발생했는지를 알 수 있습니다.You will then know whether the error is somewhere inside the half you removed (which you should now restore in any case) or in the half you did not remove. 문제가 더 이상 발생하지 않을 때까지 오류가 포함된 부분을 계속해서 분할하면서 프로세스를 반복합니다.Repeat the process by splitting the half that contains the error, and so on, until you've zeroed in on the issue.

증상 및 해결 방법Symptoms and remedies

증상Symptom 해결 방법Remedy
HRESULT 값이 REGDB_E_CLASSNOTREGISTERED일 때 런타임에서 예외가 throw됩니다.An exception is thrown at runtime with a HRESULT value of REGDB_E_CLASSNOTREGISTERED. "클래스가 등록되지 않음" 예외가 발생하는 이유는 무엇인가요?를 참조하세요.See Why am I getting a "class not registered" exception?.
C++ 컴파일러에서 “’implements_type’: ‘<projected type>’의 직접 또는 간접 기본 클래스에 속하는 멤버가 아닙니다.” 오류를 생성합니다. The C++ compiler produces the error "'implements_type': is not a member of any direct or indirect base class of '<projected type>'". 이 오류는 네임스페이스로 한정되지 않은 구현 형식 이름(예: MyRuntimeClass)으로 make를 호출하고 해당 형식의 헤더를 포함하지 않은 경우에 발생할 수 있습니다.This can happen when you call make with the namespace-unqualified name of your implementation type (MyRuntimeClass, for example), and you haven't included that type's header. 컴파일러가 MyRuntimeClass를 프로젝션된 형식으로 해석합니다.The compiler interprets MyRuntimeClass as the projected type. 해결 방법은 구현 형식의 헤더(예: MyRuntimeClass.h)를 포함하는 것입니다.The solution is to include the header for your implementation type (MyRuntimeClass.h, for example).
C++ 컴파일러에서 “삭제된 함수를 참조하려고 합니다.” 오류를 생성합니다. The C++ compiler produces the error "attempting to reference a deleted function". 이 오류는 make를 호출하고 템플릿 매개 변수로 전달하는 구현 형식에 = delete 기본 생성자가 있는 경우에 발생할 수 있습니다.This can happen when you call make and the implementation type that you pass as the template parameter has an = delete default constructor. 구현 형식의 헤더 파일을 편집하여 = delete= default로 변경합니다.Edit the implementation type's header file and change = delete to = default. 런타임 클래스의 IDL에 생성자를 추가할 수도 있습니다.You can also add a constructor into the IDL for the runtime class.
INotifyPropertyChanged를 구현했지만 XAML 바인딩이 업데이트되지 않고 UI가 PropertyChanged를 구독하지 않습니다.You've implemented INotifyPropertyChanged, but your XAML bindings are not updating (and the UI is not subscribing to PropertyChanged). XAML 태그의 바인딩 식에서 Mode=OneWay(또는 TwoWay)를 설정해야 합니다.Remember to set Mode=OneWay (or TwoWay) on your binding expression in XAML markup. XAML 컨트롤, C++/WinRT 속성에 바인딩을 참조하세요.See XAML controls; bind to a C++/WinRT property.
식별할 수 있는 컬렉션에 XAML 항목 컨트롤을 바인딩하고 있으며, 런타임에 예외가 throw되고 “매개 변수가 잘못되었습니다.” 메시지가 표시됩니다.You're binding a XAML items control to an observable collection, and an exception is thrown at runtime with the message "The parameter is incorrect". IDL 및 구현에서 식별할 수 있는 모든 컬렉션을 Windows.Foundation.Collections.IVector 형식으로 선언합니다.In your IDL and your implementation, declare any observable collection as the type Windows.Foundation.Collections.IVector. 단, Windows.Foundation.Collections.IObservableVector 를 구현하는 개체를 반환합니다. 여기서 T는 요소 형식입니다.But return an object that implements Windows.Foundation.Collections.IObservableVector, where T is your element type. XAML 항목 컨트롤, C++/WinRT 컬렉션에 바인딩을 참조하세요.See XAML items controls; bind to a C++/WinRT collection.
C++ 컴파일러에서 “‘MyImplementationType_base<MyImplementationType>’: 사용할 수 있는 적절한 기본 생성자가 없습니다.” 형식의 오류를 생성합니다. The C++ compiler produces an error of the form "'MyImplementationType_base<MyImplementationType>': no appropriate default constructor available". 이 오류는 특수한 생성자가 있는 형식에서 파생한 경우에 발생할 수 있습니다.This can happen when you have derived from a type that has a non-trivial constructor. 파생 형식의 생성자가 기본 형식의 생성자에 필요한 매개 변수를 전달해야 합니다.Your derived type's constructor needs to pass along the parameters that the base type's constructor needs. 처리된 예제는 특수 생성자가 있는 형식에서 파생을 참조하세요.For a worked example, see Deriving from a type that has a non-trivial constructor.
C++ 컴파일러에서 “‘const std::vector<std::wstring,std::allocator<_Ty>>’에서 ‘const winrt::param::async_iterable<winrt::hstring> &’로 변환할 수 없습니다.” 오류를 생성합니다. The C++ compiler produces the error "cannot convert from 'const std::vector<std::wstring,std::allocator<_Ty>>' to 'const winrt::param::async_iterable<winrt::hstring> &'". 이 오류는 std::wstring의 std::vector를 컬렉션이 필요한 Windows 런타임 API에 전달하는 경우에 발생할 수 있습니다.This can happen when you pass a std::vector of std::wstring to a Windows Runtime API that expects a collection. 자세한 내용은 표준 C++ 데이터 형식 및 C++/WinRT를 참조하세요.For more info, see Standard C++ data types and C++/WinRT.
C++ 컴파일러에서 “‘const std::vector<winrt::hstring,std::allocator<_Ty>>’에서 ‘const winrt::param::async_iterable<winrt::hstring> &’로 변환할 수 없습니다.” 오류를 생성합니다. The C++ compiler produces the error "cannot convert from 'const std::vector<winrt::hstring,std::allocator<_Ty>>' to 'const winrt::param::async_iterable<winrt::hstring> &'". 이 오류는 winrt::hstring의 std::vector를 컬렉션이 필요한 비동기 Windows 런타임 API에 전달하고, 벡터를 비동기 호출 수신자로 복사하거나 이동하지 않은 경우에 발생할 수 있습니다.This can happen when you pass a std::vector of winrt::hstring to an asynchronous Windows Runtime API that expects a collection, and you've neither copied nor moved the vector to the async callee. 자세한 내용은 표준 C++ 데이터 형식 및 C++/WinRT를 참조하세요.For more info, see Standard C++ data types and C++/WinRT.
프로젝트를 열 때 Visual Studio에서 “프로젝트에 대한 애플리케이션이 설치되어 있지 않습니다.” 오류를 생성합니다. When opening a project, Visual Studio produces the error "The application for the project is not installed". C++ 개발용 Windows 유니버설 도구를 아직 설치하지 않은 경우 Visual Studio의 새 프로젝트 대화 상자에서 설치해야 합니다.If you haven't already, you need to install Windows Universal tools for C++ development from within Visual Studio's New Project dialog. 그래도 문제가 해결되지 않으면 프로젝트에서 C++/WinRT VSIX(Visual Studio Extension)를 사용할 수 있습니다(Visual Studio의 C++/WinRT 지원 참조).If that doesn't resolve the issue, then the project may depend on the C++/WinRT Visual Studio Extension (VSIX) (see Visual Studio support for C++/WinRT.
Windows 앱 인증 키트 테스트에서 런타임 클래스 중 하나가 “Windows 기본 클래스에서 파생되지 않았습니다. 구성 가능한 모든 클래스는 궁극적으로 Windows 네임스페이스의 형식에서 파생되어야 합니다.” 오류를 생성합니다. The Windows App Certification Kit tests produce an error that one of your runtime classes "does not derive from a Windows base class. All composable classes must ultimately derive from a type in the Windows namespace". 기본 클래스에서 파생된 런타임 클래스(애플리케이션에서 선언)를 ‘구성 가능’ 클래스라고 합니다. Any runtime class (that you declare in your application) that derives from a base class is known as a composable class. 구성 가능 클래스의 최종 기본 클래스는 Windows.* 네임스페이스에서 시작되는 형식(예: Windows.UI.Xaml.DependencyObject)이어야 합니다.The ultimate base class of a composable class must be a type originating in a Windows.* namespace; for example, Windows.UI.Xaml.DependencyObject. 자세한 내용은 XAML 컨트롤, C++/WinRT 속성에 바인딩을 참조하세요.See XAML controls; bind to a C++/WinRT property for more details.
C++ 컴파일러에서 EventHandler 또는 TypedEventHandler 대리자 특수화에 대해 “WinRT 형식이어야 합니다.” 오류를 생성합니다. The C++ compiler produces a "must be WinRT type" error for an EventHandler or TypedEventHandler delegate specialization. winrt::delegate<...T> 를 대신 사용하세요.Consider using winrt::delegate<...T> instead. C++/WinRT의 이벤트 작성을 참조하세요.See Author events in C++/WinRT.
C++ 컴파일러에서 Windows 런타임 비동기 작업 특수화에 대해 “WinRT 형식이어야 합니다.” 오류를 생성합니다. The C++ compiler produces a "must be WinRT type" error for a Windows Runtime asynchronous operation specialization. PPL(병렬 패턴 라이브러리) 작업을 대신 반환하세요.Consider returning a Parallel Patterns Library (PPL) task instead. 동시성 및 비동기 작업을 참조하세요.See Concurrency and asynchronous operations.
C++ 컴파일러에서 “오류 C2220: 경고가 오류로 처리되어 생성된 ‘object’ 파일이 없습니다.” 오류를 생성합니다. The C++ compiler produces "error C2220: warning treated as error - no 'object' file generated". 경고를 수정하거나, C/C++ > 일반 > 경고를 오류로 처리아니요(/WX-) 로 설정합니다.Either correct the warning, or set C/C++ > General > Treat Warnings As Errors to No (/WX-).
개체 삭제 후 C++/WinRT 개체의 이벤트 처리기가 호출되어 앱 작동이 중단됩니다.Your app crashes because an event handler in your C++/WinRT object is called after the object has been destroyed. 이벤트 처리 대리자를 사용하여 안전하게 this 포인터 액세스를 참조하세요.See Safely accessing the this pointer with an event-handling delegate.
C++ 컴파일러에서 “오류 C2338: 약한 참조 지원에만 사용됩니다.”를 생성합니다. The C++ compiler produces "error C2338: This is only for weak ref support". 현재 winrt::no_weak_ref 마커 구조체를 템플릿 인수로 기본 클래스에 전달한 형식에 대해 약한 참조를 요청하고 있습니다.You're requesting a weak reference for a type that passed the winrt::no_weak_ref marker struct as a template argument to its base class. 약한 참조 지원 옵트아웃을 참조하세요.See Opting out of weak reference support.
C++ 링커에서 “오류 LNK2019: 확인되지 않은 외부 기호”를 생성합니다. The C++ linker produces "error LNK2019: Unresolved external symbol" 링커에서 “LNK2019: 확인되지 않은 외부 기호” 오류가 발생하는 이유는 무엇인가요?를 참조하세요.See Why is the linker giving me a "LNK2019: Unresolved external symbol" error?.
C++/WinRT에서 사용할 경우 LLVM 및 Clang 도구 체인에서 오류를 생성합니다.The LLVM and Clang toolchain produces errors when used with C++/WinRT. LLVM 및 Clang 도구 체인은 C++/WinRT에서 지원되지 않지만 내부적으로 사용하는 방법을 에뮬레이트하려는 경우 C++/WinRT로 컴파일하기 위해 LLVM/Clang을 사용할 수 있나요?에 설명된 것처럼 실험해 볼 수 있습니다.We don't support the LLVM and Clang toolchain for C++/WinRT, but if you wanted to emulate how we use it internally, then you could try an experiment such as the one described in Can I use LLVM/Clang to compile with C++/WinRT?.
C++ 컴파일러에서 프로젝션된 형식에 대해 “사용할 수 있는 적절한 기본 생성자가 없습니다.”를 생성합니다. The C++ compiler produces "no appropriate default constructor available" for a projected type. 런타임 클래스 개체의 초기화를 지연하거나 동일한 프로젝트에서 런타임 클래스를 사용 및 구현하려는 경우, std::nullptr_t 생성자를 호출해야 합니다.If you're trying to delay the initialization of a runtime class object, or to consume and implement a runtime class in the same project, then you'll need to call the std::nullptr_t constructor. 자세한 내용은 C++/WinRT를 통한 API 사용을 참조하세요.For more info, see Consume APIs with C++/WinRT.
C++ 컴파일러에서 “오류 C3861: ‘from_abi’: 식별자를 찾을 수 없습니다.” 및 base.h에서 시작되는 기타 오류를 생성합니다. The C++ compiler produces "error C3861: 'from_abi': identifier not found", and other errors originating in base.h. 이 오류는 Visual Studio 2017(버전 15.8.0 이상)을 사용 중이며 Windows SDK 버전 10.0.17134.0(Windows 10, 버전 1803)을 대상으로 지정하는 경우에 표시될 수 있습니다.You may see this error if you are using Visual Studio 2017 (version 15.8.0 or higher), and targeting the Windows SDK version 10.0.17134.0 (Windows 10, version 1803). 보다 규칙에 맞는 Windows SDK 최신 버전을 대상으로 지정하거나, 프로젝트 속성 C/C++ > 언어 > 적합성 모드: 아니요를 설정합니다. 또는 추가 옵션 아래의 프로젝트 속성 C/C++ > 언어 > 명령줄/permissive- 가 표시되는 경우 삭제합니다.Either target a later (more conformant) version of the Windows SDK, or set project property C/C++ > Language > Conformance mode: No (also, if /permissive- appears in project property C/C++ > Language > Command Line under Additional Options, then delete it).
C++ 컴파일러에서 “오류 C2039: ‘IUnknown’: ‘`global namespace’의 멤버가 아닙니다.”를 생성합니다. The C++ compiler produces "error C2039: 'IUnknown': is not a member of '`global namespace''". C++/WinRT 프로젝트의 대상을 Windows SDK 최신 버전으로 변경하는 방법을 참조하세요.See How to retarget your C++/WinRT project to a later version of the Windows SDK.
C++ 링커에서 “오류 LNK2019: 확인되지 않은 외부 기호 _WINRT_CanUnloadNow@0이 _VSDesignerCanUnloadNow@0 함수에서 참조되었습니다.”를 생성합니다. The C++ linker produces "error LNK2019: unresolved external symbol _WINRT_CanUnloadNow@0 referenced in function _VSDesignerCanUnloadNow@0" C++/WinRT 프로젝트의 대상을 Windows SDK 최신 버전으로 변경하는 방법을 참조하세요.See How to retarget your C++/WinRT project to a later version of the Windows SDK.
빌드 프로세스에서 오류 메시지 “C++/WinRT VSIX에서 더 이상 프로젝트 빌드 지원을 제공하지 않습니다. Microsoft.Windows.CppWinRT Nuget 패키지에 프로젝트 참조를 추가하세요.”를 생성합니다. The build process produces the error message The C++/WinRT VSIX no longer provides project build support. Please add a project reference to the Microsoft.Windows.CppWinRT Nuget package. Microsoft.Windows.CppWinRT NuGet 패키지를 프로젝트에 설치합니다.Install the Microsoft.Windows.CppWinRT NuGet package into your project. 자세한 내용은 이전 버전의 VSIX 확장을 참조하세요.For details, see Earlier versions of the VSIX extension.
C++ 링커에서 winrt::impl::consume_Windows_Foundation_Collections_IVector에 대한 멘션과 함께 “오류 LNK2019: 확인되지 않은 외부 기호”를 생성합니다. The C++ linker produces error LNK2019: unresolved external symbol, with a mention of winrt::impl::consume_Windows_Foundation_Collections_IVector. C++/WinRT 2.0에서는 Windows 런타임 컬렉션에서 범위 기반의 for를 사용하는 경우 이제 #include <winrt/Windows.Foundation.Collections.h>가 필요합니다.As of C++/WinRT 2.0, If you're using a range-based for on a Windows Runtime collection, then you'll now need to #include <winrt/Windows.Foundation.Collections.h>.
C++ 컴파일러에서 "오류 C4002: 함수 형식 매크로 호출 GetCurrentTime에 대한 인수가 너무 많습니다. "를 생성합니다.The C++ compiler produces "error C4002: Too many arguments for function-like macro invocation GetCurrentTime". GetCurrentTime 및/또는 TRY를 사용하여 모호성을 해결하려면 어떻게 하나요?를 참조하세요.See How do I resolve ambiguities with GetCurrentTime and/or TRY?.
C++ 컴파일러에서 "오류 C2334: '{' 앞에 예기치 않은 토큰이 있습니다. 명백한 함수 본문을 건너뜁니다. "를 생성합니다.The C++ compiler produces "error C2334: unexpected token(s) preceding '{'; skipping apparent function body". GetCurrentTime 및/또는 TRY를 사용하여 모호성을 해결하려면 어떻게 하나요?를 참조하세요.See How do I resolve ambiguities with GetCurrentTime and/or TRY?.
C++ 컴파일러에서 "GetBindingConnector가 없으므로 winrt::impl::produce<D,I>에서 추상 클래스를 인스턴스화할 수 없습니다. "를 생성합니다.The C++ compiler produces "winrt::impl::produce<D,I> cannot instantiate abstract class, due to missing GetBindingConnector". #include <winrt/Windows.UI.Xaml.Markup.h>를 수행해야 합니다.You need to #include <winrt/Windows.UI.Xaml.Markup.h>.
C++ 컴파일러에서 "오류 C2039: 'promise_type':은 'std::experimental::coroutine_traits'의 멤버가 아닙니다. "를 생성합니다.The C++ compiler produces "error C2039: 'promise_type': is not a member of 'std::experimental::coroutine_traits'". 사용자 코루틴에서 비동기 작업 개체 또는 winrt::fire_and_forget 중 하나를 반환해야 합니다.Your coroutine needs to return either an asynchronous operation object, or winrt::fire_and_forget. 동시성 및 비동기 작업을 참조하세요.See Concurrency and asynchronous operations.
사용자 프로젝트에서 " 'PopulatePropertyInfoOverride' 액세스가 모호합니다. "를 생성합니다.Your project produces "ambiguous access of 'PopulatePropertyInfoOverride'". 이 오류는 IDL에서 하나의 기본 클래스를 선언하고 XAML 태그에서 다른 기본 클래스를 선언하는 경우에 발생할 수 있습니다.This error can occur when you declare one base class in your IDL and a different base class in your XAML markup.
처음으로 C++/WinRT 솔루션을 로드하면 "프로젝트 'MyProject.vcxproj' 구성 'Debug|x86'에 대한 Designtime 빌드에 실패했습니다. IntelliSense를 사용하지 못할 수 있습니다. "를 생성합니다.Loading a C++/WinRT solution for the first time produces "Designtime build failed for project 'MyProject.vcxproj' configuration 'Debug|x86'. IntelliSense might be unavailable.". 이 IntelliSense 문제는 처음 빌드한 후 해결됩니다.This IntelliSense issue will resolve after you build for the first time.
대리자 등록 시 winrt::auto_revoke를 지정하려고 하면 winrt::hresult_no_interface 예외를 생성합니다.Attempting to specify winrt::auto_revoke when registering a delegate produces a winrt::hresult_no_interface exception. 자동 취소 대리자를 등록하지 못하는 경우를 참조하세요.See If your auto-revoke delegate fails to register.

참고

이 항목에서 질문에 대한 답변을 찾지 못한 경우, Visual Studio C++ 개발자 커뮤니티를 방문하거나 Stack Overflow의 c++-winrt 태그를 사용하여 도움말을 찾을 수 있습니다.If this topic didn't answer your question, then you might find help by visiting the Visual Studio C++ developer community, or by using the c++-winrt tag on Stack Overflow.