diff --git a/RTObjCInterop/RTObjCInterop.sln b/RTObjCInterop/RTObjCInterop.sln
new file mode 100644
index 0000000000..31dff4dacb
--- /dev/null
+++ b/RTObjCInterop/RTObjCInterop.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26117.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTObjCInterop", "RTObjCInterop\RTObjCInterop.vcxproj", "{E332B155-82FE-4038-9D20-968F8F97AC3E}"
+EndProject
+Project("{5DD5E4FA-CB73-4610-85AB-557B54E96AA9}") = "WinObjC.Frameworks.UWP.Core", "WinObjC.Frameworks.UWP.Core\WinObjC.Frameworks.UWP.Core.nuproj", "{D9206FF8-86EF-477F-A022-AB3969D55876}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E332B155-82FE-4038-9D20-968F8F97AC3E}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {E332B155-82FE-4038-9D20-968F8F97AC3E}.Debug|ARM.ActiveCfg = Debug|ARM
+ {E332B155-82FE-4038-9D20-968F8F97AC3E}.Debug|ARM.Build.0 = Debug|ARM
+ {E332B155-82FE-4038-9D20-968F8F97AC3E}.Debug|x86.ActiveCfg = Debug|Win32
+ {E332B155-82FE-4038-9D20-968F8F97AC3E}.Debug|x86.Build.0 = Debug|Win32
+ {E332B155-82FE-4038-9D20-968F8F97AC3E}.Release|Any CPU.ActiveCfg = Release|Win32
+ {E332B155-82FE-4038-9D20-968F8F97AC3E}.Release|ARM.ActiveCfg = Release|ARM
+ {E332B155-82FE-4038-9D20-968F8F97AC3E}.Release|ARM.Build.0 = Release|ARM
+ {E332B155-82FE-4038-9D20-968F8F97AC3E}.Release|x86.ActiveCfg = Release|Win32
+ {E332B155-82FE-4038-9D20-968F8F97AC3E}.Release|x86.Build.0 = Release|Win32
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Debug|ARM.ActiveCfg = Debug|ARM
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Debug|ARM.Build.0 = Debug|ARM
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Debug|x86.ActiveCfg = Debug|x86
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Debug|x86.Build.0 = Debug|x86
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Release|ARM.ActiveCfg = Release|ARM
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Release|ARM.Build.0 = Release|ARM
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Release|x86.ActiveCfg = Release|x86
+ {D9206FF8-86EF-477F-A022-AB3969D55876}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/RTObjCInterop/RTObjCInterop/RTObjCInterop.vcxproj b/RTObjCInterop/RTObjCInterop/RTObjCInterop.vcxproj
new file mode 100644
index 0000000000..44c9dc95df
--- /dev/null
+++ b/RTObjCInterop/RTObjCInterop/RTObjCInterop.vcxproj
@@ -0,0 +1,218 @@
+
+
+
+
+ Debug
+ ARM
+
+
+ Debug
+ Win32
+
+
+ Release
+ ARM
+
+
+ Release
+ Win32
+
+
+
+ {e332b155-82fe-4038-9d20-968f8f97ac3e}
+ DynamicLibrary
+ RTObjCInterop
+ en-US
+ 14.0
+ true
+ uap10.0
+ Windows Store
+ 10.0.14393.0
+ 10.0.10586.0
+ 10.0
+ Universal Windows
+ true
+
+
+
+ DynamicLibrary
+ true
+ v141
+
+
+ DynamicLibrary
+ true
+ v141
+
+
+ DynamicLibrary
+ false
+ true
+ v141
+
+
+ DynamicLibrary
+ false
+ true
+ v141
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ false
+ true
+
+
+ false
+ false
+ true
+
+
+ false
+ false
+ true
+
+
+ false
+ false
+ true
+
+
+
+ NotUsing
+ false
+
+
+ Console
+ false
+ false
+ export.def
+
+
+ -Wno-microsoft -Wno-extern-initializer -Wno-ignored-attributes -DWINAPI_FAMILY=WINAPI_FAMILY_APP -DOBJCWINRT_EXPORT=__declspec(dllexport) -ffunction-sections -fdata-sections -d2bigobj
+
+
+ $(WINOBJC_SDK_ROOT)\include;$(WINOBJC_SDK_ROOT)\include\Platform\$(TargetOsAndVersion)\;$(WINOBJC_SDK_ROOT)\Frameworks\include;$(WINOBJC_SDK_ROOT)\include\xplat;%(IncludePaths)
+
+
+
+ MultiThreadedDebugDLL
+ DEBUG=1
+
+
+
+
+ NotUsing
+ false
+ MultiThreadedDebugDLL
+
+
+ Console
+ false
+ false
+ export.def
+
+
+ -Wno-microsoft -Wno-extern-initializer -Wno-ignored-attributes -DWINAPI_FAMILY=WINAPI_FAMILY_APP -DOBJCWINRT_EXPORT=__declspec(dllexport) -ffunction-sections -fdata-sections -d2bigobj
+
+
+ $(WINOBJC_SDK_ROOT)\include;$(WINOBJC_SDK_ROOT)\include\Platform\$(TargetOsAndVersion)\;$(WINOBJC_SDK_ROOT)\Frameworks\include;$(WINOBJC_SDK_ROOT)\include\xplat;%(IncludePaths)
+
+ Full
+ true
+
+
+
+
+
+
+ NotUsing
+ false
+
+
+ Console
+ false
+ false
+ export.def
+
+
+ -Wno-microsoft -Wno-extern-initializer -Wno-ignored-attributes -DWINAPI_FAMILY=WINAPI_FAMILY_APP -DOBJCWINRT_EXPORT=__declspec(dllexport) -ffunction-sections -fdata-sections -d2bigobj
+
+
+ $(WINOBJC_SDK_ROOT)\include;$(WINOBJC_SDK_ROOT)\include\Platform\$(TargetOsAndVersion)\;$(WINOBJC_SDK_ROOT)\Frameworks\include;$(WINOBJC_SDK_ROOT)\include\xplat;%(IncludePaths)
+
+
+
+ MultiThreadedDebugDLL
+ DEBUG=1
+
+
+
+
+ NotUsing
+ false
+
+
+ Console
+ false
+ false
+ export.def
+
+
+ -Wno-microsoft -Wno-extern-initializer -Wno-ignored-attributes -DWINAPI_FAMILY=WINAPI_FAMILY_APP -DOBJCWINRT_EXPORT=__declspec(dllexport) -ffunction-sections -fdata-sections -d2bigobj
+
+
+ $(WINOBJC_SDK_ROOT)\include;$(WINOBJC_SDK_ROOT)\include\Platform\$(TargetOsAndVersion)\;$(WINOBJC_SDK_ROOT)\Frameworks\include;$(WINOBJC_SDK_ROOT)\include\xplat;%(IncludePaths)
+
+ Full
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RTObjCInterop/RTObjCInterop/RTObjCInterop.vcxproj.filters b/RTObjCInterop/RTObjCInterop/RTObjCInterop.vcxproj.filters
new file mode 100644
index 0000000000..7f9a07fc56
--- /dev/null
+++ b/RTObjCInterop/RTObjCInterop/RTObjCInterop.vcxproj.filters
@@ -0,0 +1,38 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RTObjCInterop/RTObjCInterop/dllmain.cpp b/RTObjCInterop/RTObjCInterop/dllmain.cpp
new file mode 100644
index 0000000000..1f8de0965f
--- /dev/null
+++ b/RTObjCInterop/RTObjCInterop/dllmain.cpp
@@ -0,0 +1,27 @@
+//******************************************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//******************************************************************************
+
+#include
+
+BOOL APIENTRY DllMain(HMODULE hDLL, DWORD ul_reason_for_call, LPVOID /* lpReserved */) {
+ switch (ul_reason_for_call) {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hDLL);
+ break;
+ }
+
+ return TRUE;
+}
diff --git a/RTObjCInterop/RTObjCInterop/export.def b/RTObjCInterop/RTObjCInterop/export.def
new file mode 100644
index 0000000000..3366c0134e
--- /dev/null
+++ b/RTObjCInterop/RTObjCInterop/export.def
@@ -0,0 +1,52 @@
+LIBRARY RTObjCInterop
+ EXPORTS
+ rt_dynamic_cast
+ fastEnumArrayImpl
+ fastEnumIteratorImpl
+ SizeByEnumeration
+ getPropertyValueArrayInfo
+ convertNSDictionaryToPropertySet
+ convertNSErrorToPropertySet
+ convertPropertySetToNSDictionary
+ propertyValueCreator
+ convertNSDateToWinRT
+ convertWinRTToNSDate
+ convertNSURLToWinRTStorageFile
+ convertNSURLToWinRTUri
+ convertWinRTStorageFileToNSURL
+ convertWinRTUriToNSURL
+ convertNSNumberToPropertyValue
+ convertNSStringToPropertyValue
+ _OBJC_CLASS_RTObject DATA
+ __objc_class_name_RTObject CONSTANT
+ _OBJC_CLASS_WFGUID DATA
+ __objc_class_name_WFGUID CONSTANT
+ _OBJC_CLASS_RTKeyValuePair DATA
+ __objc_class_name_RTKeyValuePair CONSTANT
+ _OBJC_CLASS_ListenerMgr DATA
+ __objc_class_name_ListenerMgr CONSTANT
+ _OBJC_CLASS_RTProxiedNSArray DATA
+ __objc_class_name_RTProxiedNSArray CONSTANT
+ _OBJC_CLASS_RTProxiedNSArrayFull DATA
+ __objc_class_name_RTProxiedNSArrayFull CONSTANT
+ _OBJC_CLASS_RTProxiedNSMutableArray DATA
+ __objc_class_name_RTProxiedNSMutableArray CONSTANT
+ _OBJC_CLASS_RTProxiedNSMutableArrayFull DATA
+ __objc_class_name_RTProxiedNSMutableArrayFull CONSTANT
+ _OBJC_CLASS_RTProxiedIterableNSArray DATA
+ __objc_class_name_RTProxiedIterableNSArray CONSTANT
+ _OBJC_CLASS_RTProxiedIterableNSArrayFull DATA
+ __objc_class_name_RTProxiedIterableNSArrayFull CONSTANT
+ _OBJC_CLASS_RTProxiedNSDictionaryKeyEnumerator DATA
+ __objc_class_name_RTProxiedNSDictionaryKeyEnumerator CONSTANT
+ _OBJC_CLASS_RTProxiedNSDictionary DATA
+ __objc_class_name_RTProxiedNSDictionary CONSTANT
+ _OBJC_CLASS_RTProxiedNSMutableDictionary DATA
+ __objc_class_name_RTProxiedNSMutableDictionary CONSTANT
+ _OBJC_CLASS_RTProxiedKeyValuePair DATA
+ __objc_class_name_RTProxiedKeyValuePair CONSTANT
+ _OBJC_CLASS_RTProxiedObservableNSMutableArray DATA
+ __objc_class_name_RTProxiedObservableNSMutableArray CONSTANT
+ _OBJC_CLASS_RTProxiedObservableNSMutableDictionary DATA
+ __objc_class_name_RTProxiedObservableNSMutableDictionary CONSTANT
+
diff --git a/RTObjCInterop/RTObjCInterop/src/InteropBase.mm b/RTObjCInterop/RTObjCInterop/src/InteropBase.mm
new file mode 100644
index 0000000000..64f4f0c1f5
--- /dev/null
+++ b/RTObjCInterop/RTObjCInterop/src/InteropBase.mm
@@ -0,0 +1,81 @@
+//******************************************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//******************************************************************************
+
+#include
+#import
+
+// TODO[5668270] This could use NSUUID, which is backed by a GUID already.
+@implementation WFGUID {
+ GUID _guid;
+}
+
+- (unsigned long)Data1 {
+ return _guid.Data1;
+}
+
+- (unsigned short)Data2 {
+ return _guid.Data2;
+}
+
+- (unsigned short)Data3 {
+ return _guid.Data3;
+}
+
+- (unsigned char*)Data4 {
+ return _guid.Data4;
+}
+
+- (void)setData1:(unsigned long)val {
+ _guid.Data1 = val;
+}
+
+- (void)setData2:(unsigned short)val {
+ _guid.Data2 = val;
+}
+
+- (void)setData3:(unsigned short)val {
+ _guid.Data3 = val;
+}
+
++ (instancetype)guidWithGUID:(const GUID)guid {
+ WFGUID* ret = [WFGUID alloc];
+ [[ret initWithGUID:guid] autorelease];
+ return ret;
+}
+
+- initWithGUID:(const GUID)guid {
+ _guid = guid;
+ return self;
+}
+
+- (GUID)guidValue {
+ return _guid;
+}
+
+@end
+
+@implementation RTKeyValuePair {
+}
+
+- (id)key {
+ return nil;
+}
+
+- (id)value {
+ return nil;
+}
+
+@end
diff --git a/RTObjCInterop/RTObjCInterop/src/ObjCHelpers.mm b/RTObjCInterop/RTObjCInterop/src/ObjCHelpers.mm
new file mode 100644
index 0000000000..dca903af18
--- /dev/null
+++ b/RTObjCInterop/RTObjCInterop/src/ObjCHelpers.mm
@@ -0,0 +1,495 @@
+//******************************************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//******************************************************************************
+
+#import
+#import
+#import
+
+namespace CommonConvertors {
+Microsoft::WRL::ComPtr _convertNSArrayToPropertyValue(id obj);
+Microsoft::WRL::ComPtr _convertToPropertyValueType(id item);
+id _convertInspectableArrayToNSArray(Microsoft::WRL::ComPtr ip);
+id _convertIntArrayToNSArray(Microsoft::WRL::ComPtr ip);
+id _convertUIntArrayToNSArray(Microsoft::WRL::ComPtr ip);
+id _convertSingleArrayToNSArray(Microsoft::WRL::ComPtr ip);
+id _convertDoubleArrayToNSArray(Microsoft::WRL::ComPtr ip);
+id _convertStringArrayToNSArray(Microsoft::WRL::ComPtr ip);
+id _convertMapToNSDictionary(Microsoft::WRL::ComPtr ip);
+id _convertPropertyValueToObjC(Microsoft::WRL::ComPtr obj);
+
+ComPtr propertyValueCreator() {
+ ComPtr propValueCreator;
+ THROW_NS_IF_FAILED(ABI::Windows::Foundation::GetActivationFactory(HString::MakeReference(L"Windows.Foundation.PropertyValue").Get(),
+ &propValueCreator));
+ return propValueCreator;
+}
+
+ComPtr _convertToPropertyValueType(id item) {
+ if (item == nil) {
+ return nullptr;
+ }
+ ComPtr propValueCreator = propertyValueCreator();
+ ComPtr propValue;
+ if ([item isKindOfClass:[NSString class]]) {
+ HSTRING hstr = ToWRLConvertor::convert(item);
+ THROW_NS_IF_FAILED(propValueCreator->CreateString(hstr, propValue.GetAddressOf()));
+ WindowsDeleteString(hstr);
+ } else if ([item isKindOfClass:[NSArray class]]) {
+ propValue = _convertNSArrayToPropertyValue(item);
+ } else if ([item isKindOfClass:[NSDictionary class]]) {
+ propValue = convertNSDictionaryToPropertySet(item);
+ } else if ([item isKindOfClass:[NSNumber class]]) {
+ const char* type = [item objCType];
+ if (strstr("cilsq", type) != NULL) {
+ THROW_NS_IF_FAILED(
+ propValueCreator->CreateInt64(ToWRLConvertor::convert(item), propValue.GetAddressOf()));
+ } else if (strstr("CILSQ", type) != NULL) {
+ THROW_NS_IF_FAILED(
+ propValueCreator->CreateUInt64(ToWRLConvertor::convert(item), propValue.GetAddressOf()));
+ } else if (strcmp("f", type) == 0) {
+ THROW_NS_IF_FAILED(
+ propValueCreator->CreateSingle(ToWRLConvertor::convert(item), propValue.GetAddressOf()));
+ } else if (strcmp("d", type) == 0) {
+ THROW_NS_IF_FAILED(
+ propValueCreator->CreateDouble(ToWRLConvertor::convert(item), propValue.GetAddressOf()));
+ }
+ }
+ return propValue;
+}
+
+ComPtr _convertNSArrayToPropertyValue(id obj) {
+ if (obj == nil) {
+ return nullptr;
+ }
+ ComPtr propValueCreator = propertyValueCreator();
+ // This array will maintain the lifetime of the ComPtrs till the function exits.
+ std::vector> arr;
+ std::vector arrIInspectable;
+ for (id item in obj) {
+ ComPtr comObj = _convertToPropertyValueType(item);
+ arr.push_back(comObj.Get());
+ arrIInspectable.push_back(comObj.Detach());
+ }
+ ComPtr returnObj;
+ if (arrIInspectable.size()) {
+ THROW_NS_IF_FAILED(
+ propValueCreator->CreateInspectableArray(arrIInspectable.size(), arrIInspectable.data(), returnObj.GetAddressOf()));
+ }
+ return returnObj;
+}
+
+ComPtr convertNSDictionaryToPropertySet(id obj) {
+ if (obj == nil) {
+ return nullptr;
+ }
+ ComPtr propertySet;
+ Windows::Foundation::ActivateInstance(HString::MakeReference(L"Windows.Foundation.Collections.PropertySet").Get(), &propertySet);
+ ComPtr> _map;
+ ComPtr> _mapView;
+ THROW_NS_IF_FAILED(propertySet.As(&_map));
+ boolean replaced;
+ for (id key in obj) {
+ if ([key isKindOfClass:[NSString class]]) {
+ id value = obj[key];
+ ComPtr propValue = _convertToPropertyValueType(value);
+ _map->Insert(nsStrToHstr(key).Get(), propValue.Get(), &replaced);
+ }
+ }
+ THROW_NS_IF_FAILED(_map->GetView(_mapView.GetAddressOf()));
+ return _mapView;
+}
+
+ComPtr convertNSErrorToPropertySet(id obj) {
+ if (obj == nil) {
+ return nullptr;
+ }
+ ComPtr propertySet;
+ Windows::Foundation::ActivateInstance(HString::MakeReference(L"Windows.Foundation.Collections.PropertySet").Get(), &propertySet);
+ ComPtr> _map;
+ ComPtr> _mapView;
+ THROW_NS_IF_FAILED(propertySet.As(&_map));
+ ComPtr propValue = _convertToPropertyValueType([NSNumber numberWithLongLong:(int64_t)[obj code]]);
+ NSString* code = @"code";
+ boolean replaced;
+ _map->Insert(nsStrToHstr(code).Get(), propValue.Get(), &replaced);
+ id userInfo = [obj userInfo];
+ for (id key in userInfo) {
+ if ([key isKindOfClass:[NSString class]]) {
+ id value = userInfo[key];
+ propValue = _convertToPropertyValueType(value);
+ _map->Insert(nsStrToHstr(key).Get(), propValue.Get(), &replaced);
+ }
+ }
+ THROW_NS_IF_FAILED(_map->GetView(_mapView.GetAddressOf()));
+ return _mapView;
+}
+
+id _convertMapToNSDictionary(ComPtr ip) {
+ if (ip == nullptr) {
+ return nil;
+ }
+ id value;
+ ComPtr> _map;
+ ComPtr> _mapView;
+ if (SUCCEEDED(ip.As(&_map))) {
+ THROW_NS_IF_FAILED(_map->GetView(_mapView.GetAddressOf()));
+ value = convertPropertySetToNSDictionary(_mapView);
+ } else if (SUCCEEDED(ip.As(&_mapView))) {
+ value = convertPropertySetToNSDictionary(_mapView);
+ } else {
+ THROW_NS_HR(E_NOINTERFACE);
+ }
+ return value;
+}
+
+id _convertPropertyValueToObjC(ComPtr obj) {
+ if (obj == nullptr) {
+ return nil;
+ }
+ PropertyType type;
+ THROW_NS_IF_FAILED(obj->get_Type(&type));
+ id value;
+ switch (type) {
+ case PropertyType_Inspectable: {
+ value = _convertMapToNSDictionary(obj);
+ break;
+ }
+ case PropertyType_InspectableArray: {
+ value = _convertInspectableArrayToNSArray(obj);
+ break;
+ }
+ case PropertyType_Int64Array:
+ case PropertyType_Int32Array:
+ case PropertyType_Int16Array:
+ case PropertyType_Char16Array:
+ case PropertyType_BooleanArray: {
+ value = _convertIntArrayToNSArray(obj);
+ break;
+ }
+ case PropertyType_UInt64Array:
+ case PropertyType_UInt32Array:
+ case PropertyType_UInt16Array:
+ case PropertyType_UInt8Array: {
+ value = _convertUIntArrayToNSArray(obj);
+ break;
+ }
+ case PropertyType_SingleArray: {
+ value = _convertSingleArrayToNSArray(obj);
+ ;
+ break;
+ }
+ case PropertyType_DoubleArray: {
+ value = _convertDoubleArrayToNSArray(obj);
+ break;
+ }
+ case PropertyType_StringArray: {
+ value = _convertStringArrayToNSArray(obj);
+ break;
+ }
+ case PropertyType_String: {
+ HSTRING val;
+ THROW_NS_IF_FAILED(obj->GetString(&val));
+ value = hstrToNSStr(val, true);
+ break;
+ }
+ case PropertyType_Single: {
+ FLOAT val;
+ THROW_NS_IF_FAILED(obj->GetSingle(&val));
+ value = ToObjcConvertor::convert(val);
+ break;
+ }
+ case PropertyType_Double: {
+ double val;
+ THROW_NS_IF_FAILED(obj->GetDouble(&val));
+ value = ToObjcConvertor::convert(val);
+ break;
+ }
+ case PropertyType_Int64:
+ case PropertyType_Int32:
+ case PropertyType_Int16:
+ case PropertyType_Char16:
+ case PropertyType_Boolean: {
+ INT64 val;
+ THROW_NS_IF_FAILED(obj->GetInt64(&val));
+ value = ToObjcConvertor::convert(val);
+ break;
+ }
+ case PropertyType_UInt64:
+ case PropertyType_UInt32:
+ case PropertyType_UInt16:
+ case PropertyType_UInt8: {
+ UINT64 val;
+ THROW_NS_IF_FAILED(obj->GetUInt64(&val));
+ value = ToObjcConvertor::convert(val);
+ break;
+ }
+ default:
+ return nil;
+ }
+ return value;
+}
+
+id _convertStringArrayToNSArray(ComPtr ip) {
+ UINT32 length;
+ HSTRING* arr;
+ if (ip == nullptr) {
+ return nil;
+ }
+ NSMutableArray* values = [[[NSMutableArray alloc] init] autorelease];
+ THROW_NS_IF_FAILED(ip->GetStringArray(&length, &arr));
+ for (UINT32 i = 0; i < length; i++) {
+ [values addObject:hstrToNSStr(arr[i], true)];
+ }
+ NSArray* value = [NSArray arrayWithArray:values];
+ CoTaskMemFree(arr);
+ return value;
+}
+
+id _convertDoubleArrayToNSArray(ComPtr ip) {
+ UINT32 length;
+ DOUBLE* arr;
+ if (ip == nullptr) {
+ return nil;
+ }
+ NSMutableArray* values = [[[NSMutableArray alloc] init] autorelease];
+ THROW_NS_IF_FAILED(ip->GetDoubleArray(&length, &arr));
+ for (UINT32 i = 0; i < length; i++) {
+ [values addObject:[NSNumber numberWithDouble:arr[i]]];
+ }
+ NSArray* value = [NSArray arrayWithArray:values];
+ CoTaskMemFree(arr);
+ return value;
+}
+
+id _convertSingleArrayToNSArray(ComPtr ip) {
+ UINT32 length;
+ FLOAT* arr;
+ if (ip == nullptr) {
+ return nil;
+ }
+ NSMutableArray* values = [[[NSMutableArray alloc] init] autorelease];
+ THROW_NS_IF_FAILED(ip->GetSingleArray(&length, &arr));
+ for (UINT32 i = 0; i < length; i++) {
+ [values addObject:[NSNumber numberWithFloat:arr[i]]];
+ }
+ NSArray* value = [NSArray arrayWithArray:values];
+ CoTaskMemFree(arr);
+ return value;
+}
+
+id _convertUIntArrayToNSArray(ComPtr ip) {
+ UINT32 length;
+ UINT64* arr;
+ if (ip == nullptr) {
+ return nil;
+ }
+ NSMutableArray* values = [[[NSMutableArray alloc] init] autorelease];
+ THROW_NS_IF_FAILED(ip->GetUInt64Array(&length, &arr));
+ for (UINT32 i = 0; i < length; i++) {
+ [values addObject:[NSNumber numberWithUnsignedLongLong:arr[i]]];
+ }
+ NSArray* value = [NSArray arrayWithArray:values];
+ CoTaskMemFree(arr);
+ return value;
+}
+
+id _convertIntArrayToNSArray(ComPtr ip) {
+ UINT32 length;
+ INT64* arr;
+ if (ip == nullptr) {
+ return nil;
+ }
+ NSMutableArray* values = [[[NSMutableArray alloc] init] autorelease];
+ THROW_NS_IF_FAILED(ip->GetInt64Array(&length, &arr));
+ for (UINT32 i = 0; i < length; i++) {
+ [values addObject:[NSNumber numberWithLongLong:arr[i]]];
+ }
+ NSArray* value = [NSArray arrayWithArray:values];
+ CoTaskMemFree(arr);
+ return value;
+}
+
+id _convertInspectableArrayToNSArray(ComPtr ip) {
+ UINT32 length;
+ IInspectable** arr;
+ if (ip == nullptr) {
+ return nil;
+ }
+ NSMutableArray* values = [[[NSMutableArray alloc] init] autorelease];
+ THROW_NS_IF_FAILED(ip->GetInspectableArray(&length, &arr));
+ for (UINT32 i = 0; i < length; i++) {
+ ComPtr com = arr[i];
+ ComPtr propValue;
+ THROW_NS_IF_FAILED(com.As(&propValue));
+ [values addObject:_convertPropertyValueToObjC(propValue)];
+ }
+ NSArray* value = [NSArray arrayWithArray:values];
+ CoTaskMemFree(arr);
+ return value;
+}
+
+id convertPropertySetToNSDictionary(ComPtr> ip) {
+ ComPtr*>> iterable;
+ ComPtr*>> iterator;
+ if (ip == nullptr) {
+ return nil;
+ }
+ THROW_NS_IF_FAILED(ip.As(&iterable));
+ THROW_NS_IF_FAILED(iterable->First(&iterator));
+ boolean hasCurrent = false;
+ THROW_NS_IF_FAILED(iterator->get_HasCurrent(&hasCurrent));
+ NSMutableDictionary* _dictionary = [[[NSMutableDictionary alloc] init] autorelease];
+ while (hasCurrent) {
+ ComPtr> kvp;
+ THROW_NS_IF_FAILED(iterator->get_Current(&kvp));
+ HSTRING keyHstr;
+ THROW_NS_IF_FAILED(kvp->get_Key(&keyHstr));
+ NSString* key = hstrToNSStr(keyHstr, true);
+ id value;
+ ComPtr obj;
+ THROW_NS_IF_FAILED(kvp->get_Value(obj.GetAddressOf()));
+ ComPtr obj1;
+ ComPtr> obj2;
+ ComPtr> obj3;
+ if (SUCCEEDED(obj.As(&obj1))) {
+ value = _convertPropertyValueToObjC(obj1);
+ } else if (SUCCEEDED(obj.As(&obj2)) || SUCCEEDED(obj.As(&obj3))) {
+ value = _convertMapToNSDictionary(obj);
+ } else {
+ THROW_NS_HR(E_NOINTERFACE);
+ }
+ [_dictionary setObject:value forKey:key];
+ THROW_NS_IF_FAILED(iterator->MoveNext(&hasCurrent));
+ }
+ NSDictionary* _ret = [NSDictionary dictionaryWithDictionary:_dictionary];
+ return _ret;
+}
+
+ABI::Windows::Foundation::DateTime convertNSDateToWinRT(NSDate* obj) {
+ const int64_t hundredNanoSecondsFactor = 10000000;
+ // This constant is the summation of two 100 nanosecond ticks constants, first one (116444736000000000) is for
+ // converting Windows epoch (Jan 1 1601 00:00:00) to Unix epoch (Jan 1 1970 00:00:00) and
+ // the other (9783072000000000) is for converting from Unix epoch to NSDate's reference date (Jan 1 2001 00:00:00).
+ const int64_t hundredNanoSecondTicksFromWindowsEpochToNSDateReferenceDate = 126227808000000000;
+ // The time interval we get from NSDate is in seconds. We convert it to 100 nanoseconds ticks.
+ int64_t timeInterval = (int64_t)([obj timeIntervalSinceReferenceDate] * hundredNanoSecondsFactor);
+ timeInterval = timeInterval + hundredNanoSecondTicksFromWindowsEpochToNSDateReferenceDate;
+ ABI::Windows::Foundation::DateTime date;
+ date.UniversalTime = timeInterval;
+ return date;
+}
+
+NSDate* convertWinRTToNSDate(ABI::Windows::Foundation::DateTime dt) {
+ const int64_t hundredNanoSecondsFactor = 10000000;
+ const int64_t hundredNanoSecondTicksFromWindowsEpochToNSDateReferenceDate = 126227808000000000;
+ // timeInterval is 100 nanosecond ticks from Jan 1 1601 00:00.
+ // Convert timeInterval to 100 nanosecond ticks from Jan 1 2001.
+ double timeInterval = dt.UniversalTime - hundredNanoSecondTicksFromWindowsEpochToNSDateReferenceDate;
+ // Convert 100 nanosecond ticks to seconds;
+ timeInterval = timeInterval / hundredNanoSecondsFactor;
+ NSDate* date = [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
+ return date;
+}
+
+ComPtr convertNSURLToWinRTStorageFile(NSURL* obj) {
+ return nullptr;
+}
+
+ComPtr convertNSURLToWinRTUri(NSURL* obj) {
+ ComPtr uriFactory;
+ ComPtr comObj;
+ THROW_NS_IF_FAILED(
+ ABI::Windows::Foundation::GetActivationFactory(HString::MakeReference(L"Windows.Foundation.Uri").Get(), &uriFactory));
+ THROW_NS_IF_FAILED(uriFactory->CreateUri(nsStrToHstr([obj absoluteString]).Get(), comObj.GetAddressOf()));
+ return comObj;
+}
+
+NSURL* convertWinRTStorageFileToNSURL(const ComPtr storageFile) {
+ NSURL* n = [NSURL URLWithStorageFile:storageFile.Get()];
+ return n;
+}
+
+NSURL* convertWinRTUriToNSURL(const ComPtr uri) {
+ HSTRING hstr;
+ THROW_NS_IF_FAILED(uri->get_AbsoluteUri(&hstr));
+ return [NSURL URLWithString:hstrToNSStr(hstr, true)];
+}
+
+ComPtr convertNSNumberToPropertyValue(NSNumber* obj) {
+ ComPtr inst;
+ THROW_NS_IF_FAILED(
+ ABI::Windows::Foundation::GetActivationFactory(HString::MakeReference(L"Windows.Foundation.PropertyValue").Get(), &inst));
+ ComPtr ret;
+ const char* type = [obj objCType];
+ if (strstr("cC", type) != NULL) {
+ THROW_NS_IF_FAILED(inst->CreateUInt8(ToWRLConvertor::convert(obj), ret.GetAddressOf()));
+ return ret;
+ }
+
+ if (strstr("il", type) != NULL) {
+ THROW_NS_IF_FAILED(inst->CreateInt32(ToWRLConvertor::convert(obj), ret.GetAddressOf()));
+ return ret;
+ }
+
+ if (strstr("s", type) != NULL) {
+ THROW_NS_IF_FAILED(inst->CreateInt16(ToWRLConvertor::convert(obj), ret.GetAddressOf()));
+ return ret;
+ }
+
+ if (strstr("q", type) != NULL) {
+ THROW_NS_IF_FAILED(inst->CreateInt64(ToWRLConvertor::convert(obj), ret.GetAddressOf()));
+ return ret;
+ }
+
+ if (strstr("IL", type) != NULL) {
+ THROW_NS_IF_FAILED(inst->CreateUInt32(ToWRLConvertor::convert(obj), ret.GetAddressOf()));
+ return ret;
+ }
+
+ if (strstr("S", type) != NULL) {
+ THROW_NS_IF_FAILED(inst->CreateUInt16(ToWRLConvertor::convert(obj), ret.GetAddressOf()));
+ return ret;
+ }
+
+ if (strstr("Q", type) != NULL) {
+ THROW_NS_IF_FAILED(inst->CreateUInt64(ToWRLConvertor::convert(obj), ret.GetAddressOf()));
+ return ret;
+ }
+
+ if (strcmp("f", type) == 0) {
+ THROW_NS_IF_FAILED(inst->CreateSingle(ToWRLConvertor::convert(obj), ret.GetAddressOf()));
+ return ret;
+ }
+
+ if (strcmp("d", type) == 0) {
+ THROW_NS_IF_FAILED(inst->CreateDouble(ToWRLConvertor::convert(obj), ret.GetAddressOf()));
+ return ret;
+ }
+
+ return nullptr;
+}
+
+ComPtr convertNSStringToPropertyValue(NSString* obj) {
+ ComPtr inst;
+ THROW_NS_IF_FAILED(
+ ABI::Windows::Foundation::GetActivationFactory(HString::MakeReference(L"Windows.Foundation.PropertyValue").Get(), &inst));
+ ComPtr ret;
+ Microsoft::WRL::Wrappers::HString hstr;
+ hstr.Attach(ToWRLConvertor::convert(obj));
+ THROW_NS_IF_FAILED(inst->CreateString(hstr.Get(), ret.GetAddressOf()));
+ return ret;
+}
+} // namespace CommonConvertors
diff --git a/RTObjCInterop/RTObjCInterop/src/RTHelpers.mm b/RTObjCInterop/RTObjCInterop/src/RTHelpers.mm
new file mode 100644
index 0000000000..830348fd7c
--- /dev/null
+++ b/RTObjCInterop/RTObjCInterop/src/RTHelpers.mm
@@ -0,0 +1,631 @@
+//******************************************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//******************************************************************************
+
+#import
+#import
+#import
+#import
+
+using namespace Microsoft::WRL;
+
+NSUInteger fastEnumArrayImpl(id self, NSFastEnumerationState* state, id* buffer, NSUInteger len) {
+ NSUInteger count = 0;
+ NSUInteger first = state->state;
+ NSUInteger arrayLen = [self count];
+
+ if (first == 0) {
+ state->itemsPtr = buffer;
+ state->mutationsPtr = &state->extra[0];
+ }
+
+ while ((count < len) && ((first + count) < arrayLen)) {
+ buffer[count] = [self objectAtIndex:first + count];
+ count++;
+ }
+
+ state->state = first + count;
+ return count;
+}
+
+NSUInteger fastEnumIteratorImpl(id self, NSFastEnumerationState* state, id* buffer, NSUInteger len) {
+ NSUInteger count = 0;
+
+ if (state->state == 0) {
+ state->itemsPtr = buffer;
+ state->mutationsPtr = &state->extra[0];
+
+ state->state = 1;
+ buffer[count] = [self first];
+ if (buffer[count] == nil) {
+ state->state = 2;
+ return 0;
+ }
+ count++;
+ }
+
+ if (state->state == 1) {
+ while (count < len) {
+ buffer[count] = [self next];
+ if (buffer[count] == nil) {
+ state->state = 2;
+ break;
+ }
+ count++;
+ }
+ }
+
+ return count;
+}
+
+UINT32 SizeByEnumeration(id obj) {
+ NSFastEnumerationState state = { 0 };
+ UINT32 totalCount = 0;
+ id items[16] = { 0 };
+ for (;;) {
+ int count = [obj countByEnumeratingWithState:&state objects:items count:ARRAY_COUNT(items)];
+ if (!count)
+ break;
+ totalCount += (UINT32)count;
+ }
+ return totalCount;
+}
+
+void getPropertyValueArrayInfo(ComPtr comPtr, unsigned int& res, void** resPtr) {
+ PropertyType type;
+ THROW_NS_IF_FAILED(comPtr->get_Type(&type));
+ switch (type) {
+ case PropertyType_UInt8Array:
+ comPtr->GetUInt8Array(&res, (BYTE**)resPtr);
+ break;
+ case PropertyType_Int16Array:
+ comPtr->GetInt16Array(&res, (INT16**)resPtr);
+ break;
+ case PropertyType_UInt16Array:
+ comPtr->GetUInt16Array(&res, (UINT16**)resPtr);
+ break;
+ case PropertyType_Int32Array:
+ comPtr->GetInt32Array(&res, (INT32**)resPtr);
+ break;
+ case PropertyType_UInt32Array:
+ comPtr->GetUInt32Array(&res, (UINT32**)resPtr);
+ break;
+ case PropertyType_Int64Array:
+ comPtr->GetInt64Array(&res, (INT64**)resPtr);
+ break;
+ case PropertyType_UInt64Array:
+ comPtr->GetUInt64Array(&res, (UINT64**)resPtr);
+ break;
+ case PropertyType_SingleArray:
+ comPtr->GetSingleArray(&res, (FLOAT**)resPtr);
+ break;
+ case PropertyType_DoubleArray:
+ comPtr->GetDoubleArray(&res, (DOUBLE**)resPtr);
+ break;
+ case PropertyType_Char16Array:
+ comPtr->GetChar16Array(&res, (WCHAR**)resPtr);
+ break;
+ case PropertyType_BooleanArray:
+ comPtr->GetBooleanArray(&res, (BOOLEAN**)resPtr);
+ break;
+ case PropertyType_StringArray:
+ comPtr->GetStringArray(&res, (HSTRING**)resPtr);
+ break;
+ case PropertyType_InspectableArray:
+ comPtr->GetInspectableArray(&res, (IInspectable***)resPtr);
+ break;
+
+ default:
+ THROW_NS_HR(E_NOTIMPL);
+ break;
+ }
+}
+
+@implementation RTProxiedNSArray
+- (ComPtr)getInternalComObj {
+ return adapter->getInternalComObj();
+}
+
+- (instancetype)initWithAdapter:(std::unique_ptr)arrayAdapter {
+ if (self = [super init]) {
+ adapter = std::move(arrayAdapter);
+ }
+ return self;
+}
+
+- (NSUInteger)count {
+ return adapter->count();
+}
+
+- (id)objectAtIndex:(NSUInteger)index {
+ return adapter->objectAtIndex(index);
+}
+
+- (BOOL)isCArray {
+ return adapter->isCArray();
+}
+
+- (void*)ptr {
+ return adapter->ptr();
+}
+@end
+
+@implementation RTProxiedNSArrayFull
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state objects:(id __unsafe_unretained[])buffer count:(NSUInteger)len {
+ return fastEnumArrayImpl(self, state, buffer, len);
+}
+@end
+
+@implementation RTProxiedNSMutableArray
+- (ComPtr)getInternalComObj {
+ return adapter->getInternalComObj();
+}
+
+- (instancetype)initWithAdapter:(std::unique_ptr)arrayAdapter {
+ if (self = [super init]) {
+ adapter = std::move(arrayAdapter);
+ }
+ return self;
+}
+
+- (NSUInteger)count {
+ return adapter->count();
+}
+
+- (id)objectAtIndex:(NSUInteger)index {
+ return adapter->objectAtIndex(index);
+}
+
+- (BOOL)isCArray {
+ return adapter->isCArray();
+}
+
+- (void*)ptr {
+ return adapter->ptr();
+}
+
+- (void)insertObject:(id)obj atIndex:(NSUInteger)idx {
+ adapter->insertObjectAtIndex(obj, idx);
+}
+
+- (void)removeObjectAtIndex:(NSUInteger)idx {
+ adapter->removeObjectAtIndex(idx);
+}
+
+- (void)addObject:(id)anObject {
+ adapter->appendObject(anObject);
+}
+
+- (void)removeLastObject {
+ [self removeObjectAtIndex:[self count] - 1];
+}
+
+- (void)replaceObjectAtIndex:(NSUInteger)idx withObject:(id)obj {
+ adapter->replaceObjectAtIndexWithObject(idx, obj);
+}
+@end
+
+@implementation RTProxiedObservableNSMutableArray {
+ StrongId _mgr;
+}
+
+- (ComPtr)getInternalComObj {
+ return adapter->getInternalComObj();
+}
+
+- (instancetype)initWithAdapter:(std::unique_ptr)arrayAdapter {
+ if (self = [super init]) {
+ _mgr.attach([[ListenerMgr alloc] initWith:self]);
+ adapter = std::move(arrayAdapter);
+ }
+ return self;
+}
+
+- (NSUInteger)count {
+ return adapter->count();
+}
+
+- (id)objectAtIndex:(NSUInteger)index {
+ return adapter->objectAtIndex(index);
+}
+
+- (BOOL)isCArray {
+ return adapter->isCArray();
+}
+
+- (void*)ptr {
+ return adapter->ptr();
+}
+
+- (void)insertObject:(id)obj atIndex:(NSUInteger)idx {
+ adapter->insertObjectAtIndex(obj, idx);
+}
+
+- (void)removeObjectAtIndex:(NSUInteger)idx {
+ adapter->removeObjectAtIndex(idx);
+}
+
+- (void)addObject:(id)anObject {
+ adapter->appendObject(anObject);
+}
+
+- (void)removeLastObject {
+ [self removeObjectAtIndex:[self count] - 1];
+}
+
+- (void)replaceObjectAtIndex:(NSUInteger)idx withObject:(id)obj {
+ adapter->replaceObjectAtIndexWithObject(idx, obj);
+}
+
+- (void)registerSelf {
+ adapter->registerSelf(self);
+}
+
+- (void)unregisterSelf {
+ adapter->unregisterSelf();
+}
+
+- (EventRegistrationToken)addObserver:(RTCollectionListener)receiver {
+ return [_mgr addObserver:receiver];
+}
+
+- (void)removeObserver:(EventRegistrationToken)receiverToken {
+ [_mgr removeObserver:receiverToken];
+}
+
+- (void)notify:(RTCollectionOperation)op at:(unsigned int)idx {
+ [_mgr notify:op value:[NSNumber numberWithUnsignedInt:idx]];
+}
+@end
+
+@implementation RTProxiedObservableNSMutableDictionary {
+ StrongId _mgr;
+}
+
+- (ComPtr)getInternalComObj {
+ return adapter->getInternalComObj();
+}
+
+- (instancetype)initWithAdapter:(std::unique_ptr)dictionaryAdapter {
+ if (self = [super init]) {
+ _mgr.attach([[ListenerMgr alloc] initWith:self]);
+ adapter = std::move(dictionaryAdapter);
+ }
+ return self;
+}
+
+- (id)objectForKey:(id)key {
+ return adapter->objectForKey(key);
+}
+
+- (id)keyEnumerator {
+ return adapter->keyEnumerator();
+}
+
+- (unsigned int)count {
+ return adapter->count();
+}
+
+- (NSArray*)allKeys {
+ return adapter->allKeys();
+}
+
+- (NSArray*)allKeysForObject:(id)obj {
+ return adapter->allKeysForObject(obj);
+}
+
+- (NSArray*)allValues {
+ return adapter->allValues();
+}
+
+- (void)setObject:(id)obj forKey:(id)key {
+ adapter->setObject(obj, key);
+}
+
+- (void)setObject:(id)obj forKeyedSubscript:(id)key {
+ adapter->setObject(obj, key);
+}
+
+- (void)removeObjectForKey:(id)key {
+ adapter->removeObjectForKey(key);
+}
+
+- (void)removeAllObjects {
+ adapter->removeAllObjects();
+}
+
+- (void)removeObjectsForKeys:(NSArray*)keys {
+ adapter->removeObjectsForKeys(keys);
+}
+
+- (void)addEntriesFromDictionary:(NSDictionary*)otherDict {
+ adapter->addEntriesFromDictionary(otherDict);
+}
+
+- (void)addEntriesFromDictionaryNoReplace:(NSDictionary*)otherDict {
+ adapter->addEntriesFromDictionaryNoReplace(otherDict);
+}
+
+- (void)setDictionary:(NSDictionary*)otherDict {
+ adapter->setDictionary(otherDict);
+}
+
+- (void)registerSelf {
+ adapter->registerSelf(self);
+}
+
+- (void)unregisterSelf {
+ adapter->unregisterSelf();
+}
+
+- (EventRegistrationToken)addObserver:(RTCollectionListener)receiver {
+ return [_mgr addObserver:receiver];
+}
+
+- (void)removeObserver:(EventRegistrationToken)receiverToken {
+ [_mgr removeObserver:receiverToken];
+}
+
+- (void)notify:(RTCollectionOperation)op atKey:(id)key {
+ [_mgr notify:op value:key];
+}
+@end
+
+@implementation RTProxiedNSMutableArrayFull
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state objects:(id __unsafe_unretained[])buffer count:(NSUInteger)len {
+ return fastEnumArrayImpl(self, state, buffer, len);
+}
+@end
+
+@implementation RTProxiedIterableNSArray
+- (ComPtr)getInternalComObj {
+ return adapter->getInternalComObj();
+}
+
+- (instancetype)initWithAdapter:(std::unique_ptr)arrayAdapter {
+ if (self = [super init]) {
+ adapter = std::move(arrayAdapter);
+ }
+ return self;
+}
+
+- (NSUInteger)count {
+ return adapter->count();
+}
+
+- (id)objectAtIndex:(NSUInteger)index {
+ return adapter->objectAtIndex(index);
+}
+
+- (BOOL)isCArray {
+ return adapter->isCArray();
+}
+
+- (void*)ptr {
+ return adapter->ptr();
+}
+
+- (id)first {
+ return adapter->first();
+}
+
+- (id)next {
+ return adapter->next();
+}
+@end
+
+@implementation RTProxiedIterableNSArrayFull
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state objects:(id __unsafe_unretained[])buffer count:(NSUInteger)len {
+ return fastEnumArrayImpl(self, state, buffer, len);
+}
+@end
+
+@implementation RTProxiedNSDictionaryKeyEnumerator
+- (id)initWithMap:(IInspectable*)map adapter:(std::unique_ptr)enumeratorAdapter {
+ if (self = [super init]) {
+ adapter = std::move(enumeratorAdapter);
+ adapter->initWithMap(map);
+ }
+
+ return self;
+}
+
+- (id)nextObject {
+ return adapter->nextObject();
+}
+@end
+
+@implementation RTProxiedNSDictionary
+- (ComPtr)getInternalComObj {
+ return adapter->getInternalComObj();
+}
+
+- (instancetype)initWithAdapter:(std::unique_ptr)dictionaryAdapter {
+ if (self = [super init]) {
+ adapter = std::move(dictionaryAdapter);
+ }
+
+ return self;
+}
+
+- (id)objectForKey:(id)key {
+ return adapter->objectForKey(key);
+}
+
+- (id)keyEnumerator {
+ return adapter->keyEnumerator();
+}
+
+- (unsigned int)count {
+ return adapter->count();
+}
+
+- (NSArray*)allKeys {
+ return adapter->allKeys();
+}
+
+- (NSArray*)allKeysForObject:(id)obj {
+ return adapter->allKeysForObject(obj);
+}
+
+- (NSArray*)allValues {
+ return adapter->allValues();
+}
+@end
+
+@implementation RTProxiedNSMutableDictionary
+- (ComPtr)getInternalComObj {
+ return adapter->getInternalComObj();
+}
+
+- (instancetype)initWithAdapter:(std::unique_ptr)dictionaryAdapter {
+ if (self = [super init]) {
+ adapter = std::move(dictionaryAdapter);
+ }
+
+ return self;
+}
+
+- (id)objectForKey:(id)key {
+ return adapter->objectForKey(key);
+}
+
+- (id)keyEnumerator {
+ return adapter->keyEnumerator();
+}
+
+- (unsigned int)count {
+ return adapter->count();
+}
+
+- (NSArray*)allKeys {
+ return adapter->allKeys();
+}
+
+- (NSArray*)allKeysForObject:(id)obj {
+ return adapter->allKeysForObject(obj);
+}
+
+- (NSArray*)allValues {
+ return adapter->allValues();
+}
+
+- (void)setObject:(id)obj forKey:(id)key {
+ adapter->setObject(obj, key);
+}
+
+- (void)setObject:(id)obj forKeyedSubscript:(id)key {
+ adapter->setObject(obj, key);
+}
+
+- (void)removeObjectForKey:(id)key {
+ adapter->removeObjectForKey(key);
+}
+
+- (void)removeAllObjects {
+ adapter->removeAllObjects();
+}
+
+- (void)removeObjectsForKeys:(NSArray*)keys {
+ adapter->removeObjectsForKeys(keys);
+}
+
+- (void)addEntriesFromDictionary:(NSDictionary*)otherDict {
+ adapter->addEntriesFromDictionary(otherDict);
+}
+
+- (void)addEntriesFromDictionaryNoReplace:(NSDictionary*)otherDict {
+ adapter->addEntriesFromDictionaryNoReplace(otherDict);
+}
+
+- (void)setDictionary:(NSDictionary*)otherDict {
+ adapter->setDictionary(otherDict);
+}
+@end
+
+@implementation RTProxiedKeyValuePair
+- (void)setAdapter:(std::unique_ptr)keyValuePairAdapter {
+ adapter = std::move(keyValuePairAdapter);
+}
+
+- (id)key {
+ return adapter->key(self.comObj);
+}
+
+- (id)value {
+ return adapter->value(self.comObj);
+}
+@end
+
+@implementation ListenerMgr {
+ id _owner;
+ StrongId _listeners;
+ __int64 _nextToken;
+}
+
+- (id)init {
+ [super init];
+ _listeners.attach([[NSMutableDictionary alloc] init]);
+ _nextToken = 1;
+ return self;
+}
+
+- (id)initWith:(id)owner {
+ [self init];
+ _owner = owner;
+ return self;
+}
+
+- (void)setOwner:(id)owner {
+ _owner = owner;
+}
+
+- (EventRegistrationToken)addObserver:(RTCollectionListener)receiver {
+ EventRegistrationToken t;
+ t.value = _nextToken;
+
+ [receiver retain];
+ [_listeners setObject:receiver forKey:[NSNumber numberWithLongLong:t.value]];
+ _nextToken++;
+
+ if ([_listeners count] == 1) {
+ [_owner registerSelf];
+ }
+
+ return t;
+}
+
+- (void)removeObserver:(EventRegistrationToken)receiverToken {
+ NSNumber* k = [NSNumber numberWithLongLong:receiverToken.value];
+ RTCollectionListener receiver = [_listeners objectForKey:k];
+ if (receiver != nil) {
+ [_listeners removeObjectForKey:k];
+ [receiver release];
+ if ([_listeners count] == 0) {
+ [_owner unregisterSelf];
+ }
+ }
+}
+
+- (void)notify:(RTCollectionOperation)op value:(id)val {
+ for (RTCollectionListener listener in [_listeners objectEnumerator]) {
+ listener(_owner, op, val);
+ }
+}
+
+- (NSArray*)listeners {
+ return [_listeners allValues];
+}
+@end
diff --git a/RTObjCInterop/RTObjCInterop/src/RTObject.mm b/RTObjCInterop/RTObjCInterop/src/RTObject.mm
new file mode 100644
index 0000000000..968dce05d4
--- /dev/null
+++ b/RTObjCInterop/RTObjCInterop/src/RTObject.mm
@@ -0,0 +1,55 @@
+//******************************************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//******************************************************************************
+
+// This has to be @impled in a .mm file because we need to create the ivars for the comptr.
+
+#import
+#import
+
+#include
+
+#import
+
+@implementation RTObject
++ (instancetype)alloc {
+ NSLog(@"Cannot allocate WinRT components through alloc/new! Use static instantiators.", NSStringFromClass(self));
+ assert(0);
+ return nil;
+}
+
++ (instancetype)createWith:(IInspectable*)obj {
+ // We need to do no checking here since we're just mimicing a base object. The real testing happens in derived classes.
+ return _createBareRTObj(obj);
+}
+
+@end
+
+id rt_dynamic_cast(Class classType, RTObject* rtObject) {
+ // Oddly, WinRT can return nullptr from successful function calls.
+ // When this happens we simply return nil to objC users.
+ // The user might not check if the object was nil and could make this call, which can result
+ // in an exception when we try to get the underlying IInspectable from the comObj using Get() method.
+ if (rtObject == nil) {
+ return nil;
+ }
+
+ if ([rtObject comObj] == nullptr) {
+ // This is unexpected.
+ THROW_NS_HR_MSG(E_UNEXPECTED, "Underlying COM object is NULL");
+ }
+
+ return [classType createWith:[rtObject comObj].Get()];
+}
diff --git a/build/WinObjC.Frameworks.UWP.Core/Readme.txt b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/Readme.txt
similarity index 100%
rename from build/WinObjC.Frameworks.UWP.Core/Readme.txt
rename to RTObjCInterop/WinObjC.Frameworks.UWP.Core/Readme.txt
diff --git a/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packageable.props b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packageable.props
new file mode 100644
index 0000000000..7a66b837f9
--- /dev/null
+++ b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packageable.props
@@ -0,0 +1,18 @@
+
+
+
+ uap10.0
+ false
+ false
+ true
+ true
+
+
+
+ <_MainProjectOutput>
+ $(IsPackable)
+ $(IsNuGetized)
+
+
+
+
\ No newline at end of file
diff --git a/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packageable.targets b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packageable.targets
new file mode 100644
index 0000000000..ae168523c2
--- /dev/null
+++ b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packageable.targets
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ <_IncludeFiles Include="$(WINOBJC_SDK_ROOT)\include\Platform\Universal Windows\**\InteropBase.h"/>
+ <_IncludeFiles Include="$(WINOBJC_SDK_ROOT)\include\Platform\Universal Windows\**\RTHelpers.h"/>
+ <_IncludeFiles Include="$(WINOBJC_SDK_ROOT)\include\Platform\Universal Windows\**\ObjCHelpers.h"/>
+ <_IncludeFiles Include="$(WINOBJC_SDK_ROOT)\include\Platform\Universal Windows\**\ObjCHelperCommonConvertors.h"/>
+ <_IncludeFiles Include="$(WINOBJC_SDK_ROOT)\include\Platform\Universal Windows\**\ObjCHelperAsyncImplementation.h"/>
+
+
+ build\include\UWP\%(Filename)%(Extension)
+
+
+
+ build\lib\$(TargetOsAndVersion)\$(PlatformTarget)\%(Filename)%(Extension)
+
+
+
+ build\lib\$(TargetOsAndVersion)\$(PlatformTarget)\%(Filename)%(Extension)
+
+
+
+
\ No newline at end of file
diff --git a/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.props b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.props
new file mode 100644
index 0000000000..530d4f1c10
--- /dev/null
+++ b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.props
@@ -0,0 +1,22 @@
+
+
+
+ WinObjC.Frameworks.UWP.Core
+ WinObjC.Frameworks.UWP.Core
+ Microsoft
+ Microsoft
+ WinObjC.Frameworks.UWP.Core
+ WinObjC.Frameworks.UWP.Core
+
+
+
+
+
+
+ Copyright © Microsoft
+ WinObjC.Frameworks.UWP.Core
+ false
+ false
+ uap10.0
+
+
\ No newline at end of file
diff --git a/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.targets b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.targets
new file mode 100644
index 0000000000..851ef183b1
--- /dev/null
+++ b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.targets
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.nuproj b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.nuproj
similarity index 65%
rename from build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.nuproj
rename to RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.nuproj
index 259704211a..fb6a0eb700 100644
--- a/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.nuproj
+++ b/RTObjCInterop/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.nuproj
@@ -1,8 +1,8 @@
-
-
+
-
+
+
Debug
@@ -35,19 +35,13 @@
-
- 59537c2b-0319-49a8-9e2e-eea635eee515
- $(MSBuildThisFileDirectory)..\..\
+ build\OutputPackages\$(Configuration)\
+ d9206ff8-86ef-477f-a022-ab3969d55876
-
-
-
-
-
@@ -55,13 +49,14 @@
PreserveNewest
-
-
-
+
+
+
+
+
+
-
-
-
\ No newline at end of file
+
diff --git a/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.props b/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.props
deleted file mode 100644
index cdf8a5f974..0000000000
--- a/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.props
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- WinObjC.Frameworks.UWP.Core
- WinObjC.Frameworks.UWP.Core
- Microsoft
- Microsoft
- WinObjC.Frameworks.UWP.Core
- WinObjC.Frameworks.UWP.Core
-
-
-
-
-
-
- Copyright © Microsoft
- WinObjC.Frameworks.UWP.Core
- https://avatars2.githubusercontent.com/u/6154722?v=3&s=200
-
-
-
\ No newline at end of file
diff --git a/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.targets b/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.targets
deleted file mode 100644
index 425f91bdfd..0000000000
--- a/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.Packaging.targets
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
- <_DepsFiles Include="$(StarboardBasePath)\deps\prebuilt\**\RTObjCInterop.dll"/>
- <_DepsFiles Include="$(StarboardBasePath)\deps\prebuilt\**\RTObjCInterop.lib"/>
-
-
- build\deps\prebuilt\%(RecursiveDir)%(Filename)%(Extension)
-
-
-
- <_IncludeFiles Include="$(StarboardBasePath)\include\Platform\Universal Windows\**\InteropBase.h"/>
- <_IncludeFiles Include="$(StarboardBasePath)\include\Platform\Universal Windows\**\RTHelpers.h"/>
- <_IncludeFiles Include="$(StarboardBasePath)\include\Platform\Universal Windows\**\ObjCHelpers.h"/>
- <_IncludeFiles Include="$(StarboardBasePath)\include\Platform\Universal Windows\**\ObjCHelperCommonConvertors.h"/>
- <_IncludeFiles Include="$(StarboardBasePath)\include\Platform\Universal Windows\**\ObjCHelperAsyncImplementation.h"/>
-
-
- build\include\%(RecursiveDir)%(Filename)%(Extension)
-
-
-
- build\$(PackageId).props
-
-
- build\$(PackageId).targets
-
-
-
-
-
\ No newline at end of file
diff --git a/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.props b/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.props
deleted file mode 100644
index 405faa930b..0000000000
--- a/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.props
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.targets b/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.targets
deleted file mode 100644
index 7e41fa74be..0000000000
--- a/build/WinObjC.Frameworks.UWP.Core/WinObjC.Frameworks.UWP.Core.targets
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
- Universal Windows
-
-
-
-
-
- <_DllsFromPackage Include="$(MSBuildThisFileDirectory)\lib\$(TargetOsAndVersion)\$(PlatformTarget)\*.dll"/>
- <_DllsFromPackage Include="$(MSBuildThisFileDirectory)\lib\$(TargetOsAndVersion)\$(PlatformTarget)\$(Configuration)\*.dll"/>
-
- <_DllsFromPackage Include="$(MSBuildThisFileDirectory)\deps\prebuilt\$(TargetOsAndVersion)\$(PlatformTarget)\*.dll"/>
- <_DllsFromPackage Include="$(MSBuildThisFileDirectory)\deps\prebuilt\$(TargetOsAndVersion)\$(PlatformTarget)\$(Configuration)\*.dll"/>
-
-
-
-
-
- $(MSBuildThisFileDirectory)\include\;%(InternalSystemIncludePaths);
-
-
-
- $(MSBuildThisFileDirectory)\lib\$(TargetOsAndVersion)\$(PlatformTarget)\;$(MSBuildThisFileDirectory)\lib\$(TargetOsAndVersion)\$(PlatformTarget)\$(Configuration)\;$(MSBuildThisFileDirectory)\deps\prebuilt\$(TargetOsAndVersion)\$(PlatformTarget)\;$(MSBuildThisFileDirectory)\deps\prebuilt\$(TargetOsAndVersion)\$(PlatformTarget)\$(Configuration)\;%(AdditionalLibraryDirectories);
- RTObjCInterop.lib;%(AdditionalDependencies);
-
-
-
-
-
-
-
- true
-
-
-
-
\ No newline at end of file
diff --git a/build/build.sln b/build/build.sln
index 62338d69ed..1f6fa82e92 100644
--- a/build/build.sln
+++ b/build/build.sln
@@ -791,8 +791,6 @@ Project("{5DD5E4FA-CB73-4610-85AB-557B54E96AA9}") = "WinObjC.Frameworks.ThirdPar
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WinObjC Frameworks UWP Core Package", "WinObjC Frameworks UWP Core Package", "{6950E151-2219-4A37-9137-0AEAE08428E4}"
EndProject
-Project("{5DD5E4FA-CB73-4610-85AB-557B54E96AA9}") = "WinObjC.Frameworks.UWP.Core", "WinObjC.Frameworks.UWP.Core\WinObjC.Frameworks.UWP.Core.nuproj", "{59537C2B-0319-49A8-9E2E-EEA635EEE515}"
-EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "NuprojInitializer", "..\common\NuprojInitializer.msbuildproj", "{417B0D00-F90E-47BB-9085-BE7E412C9DA8}"
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "NugetRestore", "..\common\NugetRestore.msbuildproj", "{B2C6186E-B340-49D8-888E-76ED83752E43}"
@@ -2313,18 +2311,6 @@ Global
{DFDF94D9-2A0A-4F9B-953B-6BF383858AD3}.Release|ARM.Build.0 = Release|ARM
{DFDF94D9-2A0A-4F9B-953B-6BF383858AD3}.Release|x86.ActiveCfg = Release|x86
{DFDF94D9-2A0A-4F9B-953B-6BF383858AD3}.Release|x86.Build.0 = Release|x86
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Debug|ARM.ActiveCfg = Debug|ARM
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Debug|ARM.Build.0 = Debug|ARM
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Debug|x86.ActiveCfg = Debug|x86
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Debug|x86.Build.0 = Debug|x86
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Release|Any CPU.Build.0 = Release|Any CPU
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Release|ARM.ActiveCfg = Release|ARM
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Release|ARM.Build.0 = Release|ARM
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Release|x86.ActiveCfg = Release|x86
- {59537C2B-0319-49A8-9E2E-EEA635EEE515}.Release|x86.Build.0 = Release|x86
{417B0D00-F90E-47BB-9085-BE7E412C9DA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{417B0D00-F90E-47BB-9085-BE7E412C9DA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{417B0D00-F90E-47BB-9085-BE7E412C9DA8}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -2730,7 +2716,6 @@ Global
{BEF15618-E03F-4A44-A797-9150C979B09F} = {F0F1B2A3-6924-4A09-99CE-D08CD8BCF392}
{60A07842-5D75-45E8-9FCF-C126E608B654} = {7B338049-F463-44B0-B7BD-F8EA16750085}
{DFDF94D9-2A0A-4F9B-953B-6BF383858AD3} = {4BC1549F-F4C2-42D0-9F77-C323F751EA04}
- {59537C2B-0319-49A8-9E2E-EEA635EEE515} = {6950E151-2219-4A37-9137-0AEAE08428E4}
{417B0D00-F90E-47BB-9085-BE7E412C9DA8} = {7B338049-F463-44B0-B7BD-F8EA16750085}
{B2C6186E-B340-49D8-888E-76ED83752E43} = {7B338049-F463-44B0-B7BD-F8EA16750085}
{C881C664-A5BA-455A-AC87-388DC1B69102} = {E1BA5F74-6863-437D-9AF5-72666F6D25B5}