ICU-20419 Export internal StackUResourceBundle helper, so it can be used in the i18n library.
Replace all current usages of ures_initStackObject() in the i18n library with the StackUResourceBundle helper.
diff --git a/icu4c/source/common/uresimp.h b/icu4c/source/common/uresimp.h
index de3348e..71c5959 100644
--- a/icu4c/source/common/uresimp.h
+++ b/icu4c/source/common/uresimp.h
@@ -106,7 +106,7 @@
  * @see LocalUResourceBundlePointer
  * @internal
  */
-class StackUResourceBundle {
+class U_COMMON_API StackUResourceBundle {
 public:
     // No heap allocation. Use only on the stack.
     static void* U_EXPORT2 operator new(size_t) U_NO_THROW = delete;
@@ -120,6 +120,9 @@
 
     UResourceBundle* getAlias() { return &bundle; }
 
+    UResourceBundle& ref() { return bundle; }
+    const UResourceBundle& ref() const { return bundle; }
+
     StackUResourceBundle(const StackUResourceBundle&) = delete;
     StackUResourceBundle& operator=(const StackUResourceBundle&) = delete;
 
diff --git a/icu4c/source/common/wintz.cpp b/icu4c/source/common/wintz.cpp
index 8a143d9..115512e 100644
--- a/icu4c/source/common/wintz.cpp
+++ b/icu4c/source/common/wintz.cpp
@@ -86,19 +86,18 @@
     }
 
     if (dynamicTZI.TimeZoneKeyName[0] != 0) {
-        UResourceBundle winTZ;
-        ures_initStackObject(&winTZ);
-        ures_getByKey(bundle.getAlias(), dynamicTZKeyName, &winTZ, &status);
-        
+        StackUResourceBundle winTZ;
+        ures_getByKey(bundle.getAlias(), dynamicTZKeyName, winTZ.getAlias(), &status);
+
         if (U_SUCCESS(status)) {
             const UChar* icuTZ = nullptr;
             if (errorCode != 0) {
-                icuTZ = ures_getStringByKey(&winTZ, ISOcode, &len, &status);
+                icuTZ = ures_getStringByKey(winTZ.getAlias(), ISOcode, &len, &status);
             }
             if (errorCode == 0 || icuTZ == nullptr) {
                 /* fallback to default "001" and reset status */
                 status = U_ZERO_ERROR;
-                icuTZ = ures_getStringByKey(&winTZ, "001", &len, &status);
+                icuTZ = ures_getStringByKey(winTZ.getAlias(), "001", &len, &status);
             }
 
             if (U_SUCCESS(status)) {
@@ -111,7 +110,6 @@
                 tmpid[index] = '\0';
             }
         }
-        ures_close(&winTZ);
     }
 
     // Copy the timezone ID to icuid to be returned.
diff --git a/icu4c/source/i18n/coll.cpp b/icu4c/source/i18n/coll.cpp
index d9c6b46..2298f60 100644
--- a/icu4c/source/i18n/coll.cpp
+++ b/icu4c/source/i18n/coll.cpp
@@ -226,27 +226,25 @@
     U_ASSERT(availableLocaleList == NULL);
     // for now, there is a hardcoded list, so just walk through that list and set it up.
     UResourceBundle *index = NULL;
-    UResourceBundle installed;
+    StackUResourceBundle installed;
     int32_t i = 0;
     
-    ures_initStackObject(&installed);
     index = ures_openDirect(U_ICUDATA_COLL, "res_index", &status);
-    ures_getByKey(index, "InstalledLocales", &installed, &status);
-    
+    ures_getByKey(index, "InstalledLocales", installed.getAlias(), &status);
+
     if(U_SUCCESS(status)) {
-        availableLocaleListCount = ures_getSize(&installed);
+        availableLocaleListCount = ures_getSize(installed.getAlias());
         availableLocaleList = new Locale[availableLocaleListCount];
         
         if (availableLocaleList != NULL) {
-            ures_resetIterator(&installed);
-            while(ures_hasNext(&installed)) {
+            ures_resetIterator(installed.getAlias());
+            while(ures_hasNext(installed.getAlias())) {
                 const char *tempKey = NULL;
-                ures_getNextString(&installed, NULL, &tempKey, &status);
+                ures_getNextString(installed.getAlias(), NULL, &tempKey, &status);
                 availableLocaleList[i++] = Locale(tempKey);
             }
         }
         U_ASSERT(availableLocaleListCount == i);
-        ures_close(&installed);
     }
     ures_close(index);
     ucln_i18n_registerCleanup(UCLN_I18N_COLLATOR, collator_cleanup);
diff --git a/icu4c/source/i18n/olsontz.cpp b/icu4c/source/i18n/olsontz.cpp
index 8c68d8b..7f9fe43 100644
--- a/icu4c/source/i18n/olsontz.cpp
+++ b/icu4c/source/i18n/olsontz.cpp
@@ -25,7 +25,7 @@
 #include "uassert.h"
 #include "uvector.h"
 #include <float.h> // DBL_MAX
-#include "uresimp.h" // struct UResourceBundle
+#include "uresimp.h"
 #include "zonemeta.h"
 #include "umutex.h"
 
@@ -134,12 +134,11 @@
         //        setID(ures_getKey((UResourceBundle*) res)); // cast away const
 
         int32_t len;
-        UResourceBundle r;
-        ures_initStackObject(&r);
+        StackUResourceBundle r;
 
         // Pre-32bit second transitions
-        ures_getByKey(res, kTRANSPRE32, &r, &ec);
-        transitionTimesPre32 = ures_getIntVector(&r, &len, &ec);
+        ures_getByKey(res, kTRANSPRE32, r.getAlias(), &ec);
+        transitionTimesPre32 = ures_getIntVector(r.getAlias(), &len, &ec);
         transitionCountPre32 = static_cast<int16_t>(len >> 1);
         if (ec == U_MISSING_RESOURCE_ERROR) {
             // No pre-32bit transitions
@@ -151,8 +150,8 @@
         }
 
         // 32bit second transitions
-        ures_getByKey(res, kTRANS, &r, &ec);
-        transitionTimes32 = ures_getIntVector(&r, &len, &ec);
+        ures_getByKey(res, kTRANS, r.getAlias(), &ec);
+        transitionTimes32 = ures_getIntVector(r.getAlias(), &len, &ec);
         transitionCount32 = static_cast<int16_t>(len);
         if (ec == U_MISSING_RESOURCE_ERROR) {
             // No 32bit transitions
@@ -164,8 +163,8 @@
         }
 
         // Post-32bit second transitions
-        ures_getByKey(res, kTRANSPOST32, &r, &ec);
-        transitionTimesPost32 = ures_getIntVector(&r, &len, &ec);
+        ures_getByKey(res, kTRANSPOST32, r.getAlias(), &ec);
+        transitionTimesPost32 = ures_getIntVector(r.getAlias(), &len, &ec);
         transitionCountPost32 = static_cast<int16_t>(len >> 1);
         if (ec == U_MISSING_RESOURCE_ERROR) {
             // No pre-32bit transitions
@@ -177,8 +176,8 @@
         }
 
         // Type offsets list must be of even size, with size >= 2
-        ures_getByKey(res, kTYPEOFFSETS, &r, &ec);
-        typeOffsets = ures_getIntVector(&r, &len, &ec);
+        ures_getByKey(res, kTYPEOFFSETS, r.getAlias(), &ec);
+        typeOffsets = ures_getIntVector(r.getAlias(), &len, &ec);
         if (U_SUCCESS(ec) && (len < 2 || len > 0x7FFE || (len & 1) != 0)) {
             ec = U_INVALID_FORMAT_ERROR;
         }
@@ -187,8 +186,8 @@
         // Type map data must be of the same size as the transition count
         typeMapData =  NULL;
         if (transitionCount() > 0) {
-            ures_getByKey(res, kTYPEMAP, &r, &ec);
-            typeMapData = ures_getBinary(&r, &len, &ec);
+            ures_getByKey(res, kTYPEMAP, r.getAlias(), &ec);
+            typeMapData = ures_getBinary(r.getAlias(), &len, &ec);
             if (ec == U_MISSING_RESOURCE_ERROR) {
                 // no type mapping data
                 ec = U_INVALID_FORMAT_ERROR;
@@ -199,10 +198,10 @@
 
         // Process final rule and data, if any
         const UChar *ruleIdUStr = ures_getStringByKey(res, kFINALRULE, &len, &ec);
-        ures_getByKey(res, kFINALRAW, &r, &ec);
-        int32_t ruleRaw = ures_getInt(&r, &ec);
-        ures_getByKey(res, kFINALYEAR, &r, &ec);
-        int32_t ruleYear = ures_getInt(&r, &ec);
+        ures_getByKey(res, kFINALRAW, r.getAlias(), &ec);
+        int32_t ruleRaw = ures_getInt(r.getAlias(), &ec);
+        ures_getByKey(res, kFINALYEAR, r.getAlias(), &ec);
+        int32_t ruleYear = ures_getInt(r.getAlias(), &ec);
         if (U_SUCCESS(ec)) {
             UnicodeString ruleID(TRUE, ruleIdUStr, len);
             UResourceBundle *rule = TimeZone::loadRule(top, ruleID, NULL, ec);
@@ -251,7 +250,6 @@
             // No final zone
             ec = U_ZERO_ERROR;
         }
-        ures_close(&r);
 
         // initialize canonical ID
         canonicalID = ZoneMeta::getCanonicalCLDRID(tzid, ec);
diff --git a/icu4c/source/i18n/timezone.cpp b/icu4c/source/i18n/timezone.cpp
index e614603..ccbf467 100644
--- a/icu4c/source/i18n/timezone.cpp
+++ b/icu4c/source/i18n/timezone.cpp
@@ -382,19 +382,17 @@
         return NULL;
     }
     TimeZone* z = 0;
-    UResourceBundle res;
-    ures_initStackObject(&res);
+    StackUResourceBundle res;
     U_DEBUG_TZ_MSG(("pre-err=%s\n", u_errorName(ec)));
-    UResourceBundle *top = openOlsonResource(id, res, ec);
+    UResourceBundle *top = openOlsonResource(id, res.ref(), ec);
     U_DEBUG_TZ_MSG(("post-err=%s\n", u_errorName(ec)));
     if (U_SUCCESS(ec)) {
-        z = new OlsonTimeZone(top, &res, id, ec);
+        z = new OlsonTimeZone(top, res.getAlias(), id, ec);
         if (z == NULL) {
             ec = U_MEMORY_ALLOCATION_ERROR;
             U_DEBUG_TZ_MSG(("cstz: olson time zone failed to initialize - err %s\n", u_errorName(ec)));
         }
     }
-    ures_close(&res);
     ures_close(top);
     if (U_FAILURE(ec)) {
         U_DEBUG_TZ_MSG(("cstz: failed to create, err %s\n", u_errorName(ec)));
@@ -987,18 +985,14 @@
 TimeZone::countEquivalentIDs(const UnicodeString& id) {
     int32_t result = 0;
     UErrorCode ec = U_ZERO_ERROR;
-    UResourceBundle res;
-    ures_initStackObject(&res);
+    StackUResourceBundle res;
     U_DEBUG_TZ_MSG(("countEquivalentIDs..\n"));
-    UResourceBundle *top = openOlsonResource(id, res, ec);
+    UResourceBundle *top = openOlsonResource(id, res.ref(), ec);
     if (U_SUCCESS(ec)) {
-        UResourceBundle r;
-        ures_initStackObject(&r);
-        ures_getByKey(&res, kLINKS, &r, &ec);
-        ures_getIntVector(&r, &result, &ec);
-        ures_close(&r);
+        StackUResourceBundle r;
+        ures_getByKey(res.getAlias(), kLINKS, r.getAlias(), &ec);
+        ures_getIntVector(r.getAlias(), &result, &ec);
     }
-    ures_close(&res);
     ures_close(top);
     return result;
 }
@@ -1010,24 +1004,20 @@
     U_DEBUG_TZ_MSG(("gEI(%d)\n", index));
     UnicodeString result;
     UErrorCode ec = U_ZERO_ERROR;
-    UResourceBundle res;
-    ures_initStackObject(&res);
-    UResourceBundle *top = openOlsonResource(id, res, ec);
+    StackUResourceBundle res;
+    UResourceBundle *top = openOlsonResource(id, res.ref(), ec);
     int32_t zone = -1;
     if (U_SUCCESS(ec)) {
-        UResourceBundle r;
-        ures_initStackObject(&r);
+        StackUResourceBundle r;
         int32_t size;
-        ures_getByKey(&res, kLINKS, &r, &ec);
-        const int32_t* v = ures_getIntVector(&r, &size, &ec);
+        ures_getByKey(res.getAlias(), kLINKS, r.getAlias(), &ec);
+        const int32_t *v = ures_getIntVector(r.getAlias(), &size, &ec);
         if (U_SUCCESS(ec)) {
             if (index >= 0 && index < size) {
                 zone = v[index];
             }
         }
-        ures_close(&r);
     }
-    ures_close(&res);
     if (zone >= 0) {
         UResourceBundle *ares = ures_getByKey(top, kNAMES, NULL, &ec); // dereference Zones section
         if (U_SUCCESS(ec)) {
@@ -1497,10 +1487,9 @@
 static void U_CALLCONV initTZDataVersion(UErrorCode &status) {
     ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
     int32_t len = 0;
-    UResourceBundle bundle;
-    ures_initStackObject(&bundle);
-    ures_openDirectFillIn(&bundle, NULL, kZONEINFO, &status);
-    const UChar *tzver = ures_getStringByKey(&bundle, kTZVERSION, &len, &status);
+    StackUResourceBundle bundle;
+    ures_openDirectFillIn(bundle.getAlias(), NULL, kZONEINFO, &status);
+    const UChar *tzver = ures_getStringByKey(bundle.getAlias(), kTZVERSION, &len, &status);
 
     if (U_SUCCESS(status)) {
         if (len >= (int32_t)sizeof(TZDATA_VERSION)) {
@@ -1509,7 +1498,6 @@
         }
         u_UCharsToChars(tzver, TZDATA_VERSION, len);
     }
-    ures_close(&bundle);
 }
 
 const char*
diff --git a/icu4c/source/i18n/zonemeta.cpp b/icu4c/source/i18n/zonemeta.cpp
index 9fe39a3..ddc8e29 100644
--- a/icu4c/source/i18n/zonemeta.cpp
+++ b/icu4c/source/i18n/zonemeta.cpp
@@ -784,14 +784,13 @@
 
     UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status);
     UResourceBundle *bundle = ures_getByKey(rb, gMapTimezonesTag, NULL, &status);
-    UResourceBundle res;
-    ures_initStackObject(&res);
+    StackUResourceBundle res;
     while (U_SUCCESS(status) && ures_hasNext(bundle)) {
-        ures_getNextResource(bundle, &res, &status);
+        ures_getNextResource(bundle, res.getAlias(), &status);
         if (U_FAILURE(status)) {
             break;
         }
-        const char *mzID = ures_getKey(&res);
+        const char *mzID = ures_getKey(res.getAlias());
         int32_t len = static_cast<int32_t>(uprv_strlen(mzID));
         UChar *uMzID = (UChar*)uprv_malloc(sizeof(UChar) * (len + 1));
         if (uMzID == NULL) {
@@ -809,7 +808,6 @@
             delete usMzID;
         }
     }
-    ures_close(&res);
     ures_close(bundle);
     ures_close(rb);