Internal: Use C struct ndn_Blob where possible. Make ndn::Blob work with ndn_Blob.
diff --git a/ndn-cpp/c/data.h b/ndn-cpp/c/data.h
index 6340c8c..e085f79 100644
--- a/ndn-cpp/c/data.h
+++ b/ndn-cpp/c/data.h
@@ -19,13 +19,10 @@
  * An ndn_Signature struct holds the signature bits and other info representing the signature in a data packet.
  */
 struct ndn_Signature {
-  uint8_t *digestAlgorithm;      /**< pointer to pre-allocated buffer.  0 for none.
-                                        *   If none, default is 2.16.840.1.101.3.4.2.1 (sha-256). */
-  size_t digestAlgorithmLength;  /**< length of digestAlgorithm.  0 for none */
-  uint8_t *witness;              /**< pointer to pre-allocated buffer.  0 for none. */
-  size_t witnessLength;          /**< length of witness.  0 for none */
-  uint8_t *signature;
-  size_t signatureLength;
+  struct ndn_Blob digestAlgorithm; /**< A Blob whose value is a pointer to a pre-allocated buffer.  0 for none.
+                                    *   If none, default is 2.16.840.1.101.3.4.2.1 (sha-256). */
+  struct ndn_Blob witness;         /**< A Blob whose value is a pointer to pre-allocated buffer.  0 for none. */
+  struct ndn_Blob signature;
   struct ndn_PublisherPublicKeyDigest publisherPublicKeyDigest;
   struct ndn_KeyLocator keyLocator;
 };
@@ -37,12 +34,9 @@
  * @param maxKeyNameComponents The number of elements in the allocated keyNameComponents array.
  */
 static inline void ndn_Signature_initialize(struct ndn_Signature *self, struct ndn_NameComponent *keyNameComponents, size_t maxKeyNameComponents) {
-  self->digestAlgorithm = 0;
-  self->digestAlgorithmLength = 0;
-  self->witness = 0;
-  self->witnessLength = 0;
-  self->signature = 0;
-  self->signatureLength = 0;
+  ndn_Blob_initialize(&self->digestAlgorithm, 0, 0);
+  ndn_Blob_initialize(&self->witness, 0, 0);
+  ndn_Blob_initialize(&self->signature, 0, 0);
   ndn_PublisherPublicKeyDigest_initialize(&self->publisherPublicKeyDigest);
   ndn_KeyLocator_initialize(&self->keyLocator, keyNameComponents, maxKeyNameComponents);
 }
@@ -81,8 +75,7 @@
   struct ndn_Signature signature;
   struct ndn_Name name;
   struct ndn_MetaInfo metaInfo;
-  uint8_t *content;     /**< pointer to the content */
-  size_t contentLength; /**< length of content */
+  struct ndn_Blob content;     /**< A Blob with a pointer to the content. */
 };
 
 /**
@@ -101,8 +94,7 @@
   ndn_Signature_initialize(&self->signature, keyNameComponents, maxKeyNameComponents);
   ndn_Name_initialize(&self->name, nameComponents, maxNameComponents);
   ndn_MetaInfo_initialize(&self->metaInfo);
-  self->content = 0;
-  self->contentLength = 0;
+  ndn_Blob_initialize(&self->content, 0, 0);
 }
 
 #ifdef __cplusplus
diff --git a/ndn-cpp/c/encoding/binary-xml-data.c b/ndn-cpp/c/encoding/binary-xml-data.c
index 25cf16a..0f28ff5 100644
--- a/ndn-cpp/c/encoding/binary-xml-data.c
+++ b/ndn-cpp/c/encoding/binary-xml-data.c
@@ -19,13 +19,11 @@
   
   // TODO: Check if digestAlgorithm is the same as the default, and skip it, otherwise encode it as UDATA.
 
-  if ((error = ndn_BinaryXmlEncoder_writeOptionalBlobDTagElement
-      (encoder, ndn_BinaryXml_DTag_Witness, signature->witness, signature->witnessLength)))
+  if ((error = ndn_BinaryXmlEncoder_writeOptionalBlobDTagElement(encoder, ndn_BinaryXml_DTag_Witness, &signature->witness)))
     return error;
 
   // Require a signature.
-  if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-      (encoder, ndn_BinaryXml_DTag_SignatureBits, signature->signature, signature->signatureLength)))
+  if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement(encoder, ndn_BinaryXml_DTag_SignatureBits, &signature->signature)))
     return error;
   
   if ((error = ndn_BinaryXmlEncoder_writeElementClose(encoder)))
@@ -40,15 +38,15 @@
   if ((error = ndn_BinaryXmlDecoder_readElementStartDTag(decoder, ndn_BinaryXml_DTag_Signature)))
     return error;
   
-  /* TODO: digestAlgorithm as UDATA */ signature->digestAlgorithm = 0; signature->digestAlgorithmLength = 0;
+  /* TODO: digestAlgorithm as UDATA */ signature->digestAlgorithm.value = 0; signature->digestAlgorithm.length = 0;
   
   if ((error = ndn_BinaryXmlDecoder_readOptionalBinaryDTagElement
-      (decoder, ndn_BinaryXml_DTag_Witness, 0, &signature->witness, &signature->witnessLength)))
+      (decoder, ndn_BinaryXml_DTag_Witness, 0, &signature->witness)))
     return error;
   
   // Require a signature.
   if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
-      (decoder, ndn_BinaryXml_DTag_SignatureBits, 0, &signature->signature, &signature->signatureLength)))
+      (decoder, ndn_BinaryXml_DTag_SignatureBits, 0, &signature->signature)))
     return error;
   
   if ((error = ndn_BinaryXmlDecoder_readElementClose(decoder)))
@@ -76,23 +74,22 @@
   
   if (!(metaInfo->type < 0 || metaInfo->type == ndn_ContentType_DATA)) {
     // Not the default of DATA, so we need to encode the type.
-    uint8_t *typeBytes;
-    size_t typeBytesLength = 3;
+    struct ndn_Blob typeBytes;
+    typeBytes.length = 3;
     if (metaInfo->type == ndn_ContentType_ENCR)
-      typeBytes = "\x10\xD0\x91";
+      typeBytes.value = "\x10\xD0\x91";
     else if (metaInfo->type == ndn_ContentType_GONE)
-      typeBytes = "\x18\xE3\x44";
+      typeBytes.value = "\x18\xE3\x44";
     else if (metaInfo->type == ndn_ContentType_KEY)
-      typeBytes = "\x28\x46\x3F";
+      typeBytes.value = "\x28\x46\x3F";
     else if (metaInfo->type == ndn_ContentType_LINK)
-      typeBytes = "\x2C\x83\x4A";
+      typeBytes.value = "\x2C\x83\x4A";
     else if (metaInfo->type == ndn_ContentType_NACK)
-      typeBytes = "\x34\x00\x8A";
+      typeBytes.value = "\x34\x00\x8A";
     else
       return NDN_ERROR_unrecognized_ndn_ContentType;
 
-    if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-        (encoder, ndn_BinaryXml_DTag_Type, typeBytes, typeBytesLength)))
+    if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement(encoder, ndn_BinaryXml_DTag_Type, &typeBytes)))
       return error;
   }
   
@@ -101,7 +98,7 @@
     return error;
   
   if ((error = ndn_BinaryXmlEncoder_writeOptionalBlobDTagElement
-      (encoder, ndn_BinaryXml_DTag_FinalBlockID, metaInfo->finalBlockID.value, metaInfo->finalBlockID.valueLength)))
+      (encoder, ndn_BinaryXml_DTag_FinalBlockID, &metaInfo->finalBlockID.value)))
     return error;
  
   // This will skip encoding if there is no key locator.
@@ -127,27 +124,26 @@
       (decoder, ndn_BinaryXml_DTag_Timestamp, &metaInfo->timestampMilliseconds))
     return error;
   
-  uint8_t *typeBytes;
-  size_t typeBytesLength;
+  struct ndn_Blob typeBytes;
   if ((error = ndn_BinaryXmlDecoder_readOptionalBinaryDTagElement
-      (decoder, ndn_BinaryXml_DTag_Type, 0, &typeBytes, &typeBytesLength)))
+      (decoder, ndn_BinaryXml_DTag_Type, 0, &typeBytes)))
     return error;
-  if (typeBytesLength == 0)
+  if (typeBytes.length == 0)
     // The default Type is DATA.
     metaInfo->type = ndn_ContentType_DATA;
-  else if (typeBytesLength == 3) {
+  else if (typeBytes.length == 3) {
     // All the recognized content types are 3 bytes.
-    if (ndn_memcmp(typeBytes, "\x0C\x04\xC0", typeBytesLength) == 0)
+    if (ndn_memcmp(typeBytes.value, "\x0C\x04\xC0", typeBytes.length) == 0)
       metaInfo->type = ndn_ContentType_DATA;
-    else if (ndn_memcmp(typeBytes, "\x10\xD0\x91", typeBytesLength) == 0)
+    else if (ndn_memcmp(typeBytes.value, "\x10\xD0\x91", typeBytes.length) == 0)
       metaInfo->type = ndn_ContentType_ENCR;
-    else if (ndn_memcmp(typeBytes, "\x18\xE3\x44", typeBytesLength) == 0)
+    else if (ndn_memcmp(typeBytes.value, "\x18\xE3\x44", typeBytes.length) == 0)
       metaInfo->type = ndn_ContentType_GONE;
-    else if (ndn_memcmp(typeBytes, "\x28\x46\x3F", typeBytesLength) == 0)
+    else if (ndn_memcmp(typeBytes.value, "\x28\x46\x3F", typeBytes.length) == 0)
       metaInfo->type = ndn_ContentType_KEY;
-    else if (ndn_memcmp(typeBytes, "\x2C\x83\x4A", typeBytesLength) == 0)
+    else if (ndn_memcmp(typeBytes.value, "\x2C\x83\x4A", typeBytes.length) == 0)
       metaInfo->type = ndn_ContentType_LINK;
-    else if (ndn_memcmp(typeBytes, "\x34\x00\x8A", typeBytesLength) == 0)
+    else if (ndn_memcmp(typeBytes.value, "\x34\x00\x8A", typeBytes.length) == 0)
       metaInfo->type = ndn_ContentType_NACK;
     else
       return NDN_ERROR_unrecognized_ndn_ContentType;
@@ -160,7 +156,7 @@
     return error;
 
   if ((error = ndn_BinaryXmlDecoder_readOptionalBinaryDTagElement
-      (decoder, ndn_BinaryXml_DTag_FinalBlockID, 0, &metaInfo->finalBlockID.value, &metaInfo->finalBlockID.valueLength)))
+      (decoder, ndn_BinaryXml_DTag_FinalBlockID, 0, &metaInfo->finalBlockID.value)))
     return error;
 
   if ((error = ndn_decodeOptionalBinaryXmlKeyLocator(&signature->keyLocator, decoder)))
@@ -190,8 +186,7 @@
   if ((error = encodeSignedInfo(&data->signature, &data->metaInfo, encoder)))
     return error;
 
-  if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-      (encoder, ndn_BinaryXml_DTag_Content, data->content, data->contentLength)))
+  if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement(encoder, ndn_BinaryXml_DTag_Content, &data->content)))
     return error;
 
   *signedPortionEndOffset = encoder->offset;
@@ -234,8 +229,7 @@
     ndn_MetaInfo_initialize(&data->metaInfo);
 
   // Require a Content element, but set allowNull to allow a missing BLOB.
-  if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
-      (decoder, ndn_BinaryXml_DTag_Content, 1, &data->content, &data->contentLength)))
+  if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(decoder, ndn_BinaryXml_DTag_Content, 1, &data->content)))
     return error; 
   
   *signedPortionEndOffset = decoder->offset;
diff --git a/ndn-cpp/c/encoding/binary-xml-decoder.c b/ndn-cpp/c/encoding/binary-xml-decoder.c
index 6cbb8ac..eab5cdf 100644
--- a/ndn-cpp/c/encoding/binary-xml-decoder.c
+++ b/ndn-cpp/c/encoding/binary-xml-decoder.c
@@ -140,7 +140,7 @@
 }
 
 ndn_Error ndn_BinaryXmlDecoder_readBinaryDTagElement
-  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int allowNull, uint8_t **value, size_t *valueLength)
+  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int allowNull, struct ndn_Blob *value)
 {
   ndn_Error error;
   if ((error = ndn_BinaryXmlDecoder_readElementStartDTag(self, expectedTag)))
@@ -153,8 +153,8 @@
     if (unsafeGetOctet(self) == ndn_BinaryXml_CLOSE) {
       // The binary item is missing, and this is allowed, so read the element close and return a null value.
       ++self->offset;
-      *value = 0;
-      *valueLength = 0;
+      value->value = 0;
+      value->length = 0;
       return NDN_ERROR_success;
     }
   }
@@ -164,9 +164,9 @@
   if ((error = ndn_BinaryXmlDecoder_decodeTypeAndValue(self, &itemType, &uintValueLength)))
     return error;
   // Ignore itemType.
-  *value = self->input + self->offset;
-  *valueLength = (size_t)uintValueLength;
-  self->offset += *valueLength;
+  value->value = self->input + self->offset;
+  value->length = (size_t)uintValueLength;
+  self->offset += value->length;
   
   if ((error = ndn_BinaryXmlDecoder_readElementClose(self)))
     return error;
@@ -175,26 +175,26 @@
 }
 
 ndn_Error ndn_BinaryXmlDecoder_readOptionalBinaryDTagElement
-  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int allowNull, uint8_t **value, size_t *valueLength)
+  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int allowNull, struct ndn_Blob *value)
 {
   ndn_Error error;
   int gotExpectedTag;
   if ((error = ndn_BinaryXmlDecoder_peekDTag(self, expectedTag, &gotExpectedTag)))
     return error;
   if (gotExpectedTag) {
-    if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(self, expectedTag, allowNull, value, valueLength)))
+    if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(self, expectedTag, allowNull, value)))
       return error;
   }
   else {
-    *value = 0;
-    *valueLength = 0;
+    value->value = 0;
+    value->length = 0;
   }  
   
   return NDN_ERROR_success;
 }
 
 ndn_Error ndn_BinaryXmlDecoder_readUDataDTagElement
-  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, uint8_t **value, size_t *valueLength)
+  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, struct ndn_Blob *value)
 {
   ndn_Error error;
   if ((error = ndn_BinaryXmlDecoder_readElementStartDTag(self, expectedTag)))
@@ -206,9 +206,9 @@
     return error;
   if (itemType != ndn_BinaryXml_UDATA)
     return NDN_ERROR_item_is_not_UDATA;
-  *value = self->input + self->offset;
-  *valueLength = uintValueLength;
-  self->offset += *valueLength;
+  value->value = self->input + self->offset;
+  value->length = uintValueLength;
+  self->offset += value->length;
   
   if ((error = ndn_BinaryXmlDecoder_readElementClose(self)))
     return error;
@@ -217,19 +217,19 @@
 }
 
 ndn_Error ndn_BinaryXmlDecoder_readOptionalUDataDTagElement
-  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, uint8_t **value, size_t *valueLength)
+  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, struct ndn_Blob *value)
 {
   ndn_Error error;
   int gotExpectedTag;
   if ((error = ndn_BinaryXmlDecoder_peekDTag(self, expectedTag, &gotExpectedTag)))
     return error;
   if (gotExpectedTag) {
-    if ((error = ndn_BinaryXmlDecoder_readUDataDTagElement(self, expectedTag, value, valueLength)))
+    if ((error = ndn_BinaryXmlDecoder_readUDataDTagElement(self, expectedTag, value)))
       return error;
   }
   else {
-    *value = 0;
-    *valueLength = 0;
+    value->value = 0;
+    value->length = 0;
   }  
   
   return NDN_ERROR_success;
@@ -238,13 +238,12 @@
 ndn_Error ndn_BinaryXmlDecoder_readUnsignedIntegerDTagElement
   (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, unsigned int *value)
 {
-  uint8_t *udataValue;
-  size_t udataValueLength;
+  struct ndn_Blob udataValue;
   ndn_Error error;
-  if ((error = ndn_BinaryXmlDecoder_readUDataDTagElement(self, expectedTag, &udataValue, &udataValueLength)))
+  if ((error = ndn_BinaryXmlDecoder_readUDataDTagElement(self, expectedTag, &udataValue)))
     return error;
   
-  if ((error = parseUnsignedDecimalInt(udataValue, udataValueLength, value)))
+  if ((error = parseUnsignedDecimalInt(udataValue.value, udataValue.length, value)))
     return error;
   
   return NDN_ERROR_success;
@@ -275,12 +274,11 @@
   (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, double *milliseconds)
 {
   ndn_Error error;
-  uint8_t *bytes;
-  size_t bytesLength;
-  if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(self, expectedTag, 0, &bytes, &bytesLength)))
+  struct ndn_Blob bytes;
+  if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(self, expectedTag, 0, &bytes)))
     return error;
     
-  *milliseconds = 1000.0 * ndn_BinaryXmlDecoder_unsignedBigEndianToDouble(bytes, bytesLength) / 4096.0;
+  *milliseconds = 1000.0 * ndn_BinaryXmlDecoder_unsignedBigEndianToDouble(bytes.value, bytes.length) / 4096.0;
   return NDN_ERROR_success;  
 }
 
diff --git a/ndn-cpp/c/encoding/binary-xml-decoder.h b/ndn-cpp/c/encoding/binary-xml-decoder.h
index a520a0f..3e16497 100644
--- a/ndn-cpp/c/encoding/binary-xml-decoder.h
+++ b/ndn-cpp/c/encoding/binary-xml-decoder.h
@@ -9,6 +9,7 @@
 
 #include "../common.h"
 #include "../errors.h"
+#include "../util/blob.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -71,14 +72,12 @@
  * @param expectedTag the expected value for DTAG
  * @param allowNull 1 if the binary item may be missing
  * @param value output a pointer to the binary data inside self's input buffer. However, if allowNull is 1 and the
- * binary data item is absent, then return 0.
- * @param valueLength output the length of the binary data. However, if allowNull is 1 and the
- * binary data item is absent, then return 0.
+ * binary data item is absent, then set value and length to 0.
  * @return 0 for success, else an error code, including an error if not the expected tag, or if allowNull is 0
  * and the binary data is absent
  */
 ndn_Error ndn_BinaryXmlDecoder_readBinaryDTagElement
-  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int allowNull, uint8_t **value, size_t *valueLength);
+  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int allowNull, struct ndn_Blob *value);
 
 /**
  * Peek at the next element and if it is the expectedTag, call ndn_BinaryXmlDecoder_readBinaryDTagElement.
@@ -87,13 +86,11 @@
  * @param expectedTag the expected value for DTAG
  * @param allowNull 1 if the binary item may be missing
  * @param value output a pointer to the binary data inside self's input buffer. However, if allowNull is 1 and the
- * binary data item is absent, then return 0.
- * @param valueLength output the length of the binary data. However, if allowNull is 1 and the
- * binary data item is absent, then return 0.
+ * binary data item is absent, then set value and length to 0.
  * @return 0 for success, else an error code, including if allowNull is 0 and the binary data is absent
  */
 ndn_Error ndn_BinaryXmlDecoder_readOptionalBinaryDTagElement
-  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int allowNull, uint8_t **value, size_t *valueLength);
+  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int allowNull, struct ndn_Blob *value);
 
 /**
  * Decode the header from self's input starting at offset, expecting the type to be DTAG and the value to be expectedTag.
@@ -102,11 +99,10 @@
  * @param self pointer to the ndn_BinaryXmlDecoder struct
  * @param expectedTag the expected value for DTAG
  * @param value output a pointer to the binary data inside self's input buffer.
- * @param valueLength output the length of the binary data.
  * @return 0 for success, else an error code, including an error if not the expected tag, or if the item is not UDATA.
  */
 ndn_Error ndn_BinaryXmlDecoder_readUDataDTagElement
-  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, uint8_t **value, size_t *valueLength);
+  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, struct ndn_Blob *value);
 
 /**
  * Peek at the next element and if it is the expectedTag, call ndn_BinaryXmlDecoder_readUDataDTagElement.
@@ -114,13 +110,11 @@
  * @param self pointer to the ndn_BinaryXmlDecoder struct
  * @param expectedTag the expected value for DTAG
  * @param value output a pointer to the binary data inside self's input buffer. However, if allowNull is 1 and the
- * binary data item is absent, then return 0.
- * @param valueLength output the length of the binary data. However, if allowNull is 1 and the
- * binary data item is absent, then return 0.
+ * binary data item is absent, then set value and length to 0.
  * @return 0 for success, else an error code.
  */
 ndn_Error ndn_BinaryXmlDecoder_readOptionalUDataDTagElement
-  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, uint8_t **value, size_t *valueLength);
+  (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, struct ndn_Blob *value);
 
 /**
  * Decode the header from self's input starting at offset, expecting the type to be DTAG and the value to be expectedTag.
diff --git a/ndn-cpp/c/encoding/binary-xml-encoder.c b/ndn-cpp/c/encoding/binary-xml-encoder.c
index 652de3e..10f6cd6 100644
--- a/ndn-cpp/c/encoding/binary-xml-encoder.c
+++ b/ndn-cpp/c/encoding/binary-xml-encoder.c
@@ -217,25 +217,25 @@
   return NDN_ERROR_success;
 }
 
-ndn_Error ndn_BinaryXmlEncoder_writeBlob(struct ndn_BinaryXmlEncoder *self, uint8_t *value, size_t valueLength)
+ndn_Error ndn_BinaryXmlEncoder_writeBlob(struct ndn_BinaryXmlEncoder *self, struct ndn_Blob *value)
 {
   ndn_Error error;
-  if ((error = ndn_BinaryXmlEncoder_encodeTypeAndValue(self, ndn_BinaryXml_BLOB, valueLength)))
+  if ((error = ndn_BinaryXmlEncoder_encodeTypeAndValue(self, ndn_BinaryXml_BLOB, value->length)))
     return error;
   
-  if ((error = writeArray(self, value, valueLength)))
+  if ((error = writeArray(self, value->value, value->length)))
     return error;
   
   return NDN_ERROR_success;
 }
 
-ndn_Error ndn_BinaryXmlEncoder_writeBlobDTagElement(struct ndn_BinaryXmlEncoder *self, unsigned int tag, uint8_t *value, size_t valueLength)
+ndn_Error ndn_BinaryXmlEncoder_writeBlobDTagElement(struct ndn_BinaryXmlEncoder *self, unsigned int tag, struct ndn_Blob *value)
 {
   ndn_Error error;
   if ((error = ndn_BinaryXmlEncoder_writeElementStartDTag(self, tag)))
     return error;
   
-  if ((error = ndn_BinaryXmlEncoder_writeBlob(self, value, valueLength)))
+  if ((error = ndn_BinaryXmlEncoder_writeBlob(self, value)))
     return error;  
   
   if ((error = ndn_BinaryXmlEncoder_writeElementClose(self)))
@@ -244,25 +244,25 @@
   return NDN_ERROR_success;
 }
 
-ndn_Error ndn_BinaryXmlEncoder_writeUData(struct ndn_BinaryXmlEncoder *self, uint8_t *value, size_t valueLength)
+ndn_Error ndn_BinaryXmlEncoder_writeUData(struct ndn_BinaryXmlEncoder *self, struct ndn_Blob *value)
 {
   ndn_Error error;
-  if ((error = ndn_BinaryXmlEncoder_encodeTypeAndValue(self, ndn_BinaryXml_UDATA, valueLength)))
+  if ((error = ndn_BinaryXmlEncoder_encodeTypeAndValue(self, ndn_BinaryXml_UDATA, value->length)))
     return error;
   
-  if ((error = writeArray(self, value, valueLength)))
+  if ((error = writeArray(self, value->value, value->length)))
     return error;
   
   return NDN_ERROR_success;
 }
 
-ndn_Error ndn_BinaryXmlEncoder_writeUDataDTagElement(struct ndn_BinaryXmlEncoder *self, unsigned int tag, uint8_t *value, size_t valueLength)
+ndn_Error ndn_BinaryXmlEncoder_writeUDataDTagElement(struct ndn_BinaryXmlEncoder *self, unsigned int tag, struct ndn_Blob *value)
 {
   ndn_Error error;
   if ((error = ndn_BinaryXmlEncoder_writeElementStartDTag(self, tag)))
     return error;
   
-  if ((error = ndn_BinaryXmlEncoder_writeUData(self, value, valueLength)))
+  if ((error = ndn_BinaryXmlEncoder_writeUData(self, value)))
     return error;  
   
   if ((error = ndn_BinaryXmlEncoder_writeElementClose(self)))
diff --git a/ndn-cpp/c/encoding/binary-xml-encoder.h b/ndn-cpp/c/encoding/binary-xml-encoder.h
index c457185..81fa6b9 100644
--- a/ndn-cpp/c/encoding/binary-xml-encoder.h
+++ b/ndn-cpp/c/encoding/binary-xml-encoder.h
@@ -9,6 +9,7 @@
 
 #include "../errors.h"
 #include "../util/dynamic-uint8-array.h"
+#include "../util/blob.h"
 #include "binary-xml.h"
 
 #ifdef __cplusplus
@@ -66,36 +67,33 @@
 /**
  * Write a BLOB header, then the bytes of the blob value to self->output.
  * @param self pointer to the ndn_BinaryXmlEncoder struct
- * @param value an array of bytes for the blob value
- * @param valueLength the length of the array
+ * @param value A Blob with the array of bytes for the value.
  * @return 0 for success, else an error code
  */
-ndn_Error ndn_BinaryXmlEncoder_writeBlob(struct ndn_BinaryXmlEncoder *self, uint8_t *value, size_t valueLength);
+ndn_Error ndn_BinaryXmlEncoder_writeBlob(struct ndn_BinaryXmlEncoder *self, struct ndn_Blob *value);
 
 /**
  * Write an element start header using DTAG with the tag to self->output, then the blob, then an element close.
  * (If you want to just write the blob, use ndn_BinaryXmlEncoder_writeBlob .)
  * @param self pointer to the ndn_BinaryXmlEncoder struct
  * @param tag the DTAG tag
- * @param value an array of bytes for the blob value
- * @param valueLength the length of the array
+ * @param value A Blob with the array of bytes for the value.
  * @return 0 for success, else an error code
  */
-ndn_Error ndn_BinaryXmlEncoder_writeBlobDTagElement(struct ndn_BinaryXmlEncoder *self, unsigned int tag, uint8_t *value, size_t valueLength);
+ndn_Error ndn_BinaryXmlEncoder_writeBlobDTagElement(struct ndn_BinaryXmlEncoder *self, unsigned int tag, struct ndn_Blob *value);
 
 /**
  * If value or valueLen is 0 then do nothing, otherwise call ndn_BinaryXmlEncoder_writeBlobDTagElement.
- * @param self pointer to the ndn_BinaryXmlEncoder struct
- * @param tag the DTAG tag
- * @param value an array of bytes for the blob value
- * @param valueLength the length of the array
+ * @param self A pointer to the ndn_BinaryXmlEncoder struct.
+ * @param tag The DTAG tag.
+ * @param value A Blob with the array of bytes for the value.
  * @return 0 for success, else an error code
  */
 static inline ndn_Error ndn_BinaryXmlEncoder_writeOptionalBlobDTagElement
-  (struct ndn_BinaryXmlEncoder *self, unsigned int tag, uint8_t *value, size_t valueLength)
+  (struct ndn_BinaryXmlEncoder *self, unsigned int tag, struct ndn_Blob *value)
 {
-  if (value && valueLength > 0)
-    return ndn_BinaryXmlEncoder_writeBlobDTagElement(self, tag, value, valueLength);
+  if (value->value && value->length > 0)
+    return ndn_BinaryXmlEncoder_writeBlobDTagElement(self, tag, value);
   else
     return NDN_ERROR_success;
 }
@@ -103,36 +101,33 @@
 /**
  * Write a UDATA header, then the bytes of the UDATA value to self->output.
  * @param self pointer to the ndn_BinaryXmlEncoder struct
- * @param value an array of bytes for the value
- * @param valueLength the length of the array
+ * @param value A Blob with the array of bytes for the value.
  * @return 0 for success, else an error code
  */
-ndn_Error ndn_BinaryXmlEncoder_writeUData(struct ndn_BinaryXmlEncoder *self, uint8_t *value, size_t valueLength);
+ndn_Error ndn_BinaryXmlEncoder_writeUData(struct ndn_BinaryXmlEncoder *self, struct ndn_Blob *value);
 
 /**
  * Write an element start header using DTAG with the tag to self->output, then the UDATA value, then an element close.
  * (If you want to just write the UDATA value, use ndn_BinaryXmlEncoder_writeUData .)
  * @param self pointer to the ndn_BinaryXmlEncoder struct
  * @param tag the DTAG tag
- * @param value an array of bytes for the value
- * @param valueLength the length of the array
+ * @param value A Blob with the array of bytes for the value.
  * @return 0 for success, else an error code
  */
-ndn_Error ndn_BinaryXmlEncoder_writeUDataDTagElement(struct ndn_BinaryXmlEncoder *self, unsigned int tag, uint8_t *value, size_t valueLength);
+ndn_Error ndn_BinaryXmlEncoder_writeUDataDTagElement(struct ndn_BinaryXmlEncoder *self, unsigned int tag, struct ndn_Blob *value);
 
 /**
  * If value or valueLen is 0 then do nothing, otherwise call ndn_BinaryXmlEncoder_writeUDataDTagElement.
  * @param self pointer to the ndn_BinaryXmlEncoder struct
  * @param tag the DTAG tag
- * @param value an array of bytes for the value
- * @param valueLength the length of the array
+ * @param value A Blob with the array of bytes for the value.
  * @return 0 for success, else an error code
  */
 static inline ndn_Error ndn_BinaryXmlEncoder_writeOptionalUDataDTagElement
-  (struct ndn_BinaryXmlEncoder *self, unsigned int tag, uint8_t *value, size_t valueLength)
+  (struct ndn_BinaryXmlEncoder *self, unsigned int tag, struct ndn_Blob *value)
 {
-  if (value && valueLength > 0)
-    return ndn_BinaryXmlEncoder_writeUDataDTagElement(self, tag, value, valueLength);
+  if (value->value && value->length > 0)
+    return ndn_BinaryXmlEncoder_writeUDataDTagElement(self, tag, value);
   else
     return NDN_ERROR_success;
 }
diff --git a/ndn-cpp/c/encoding/binary-xml-forwarding-entry.c b/ndn-cpp/c/encoding/binary-xml-forwarding-entry.c
index 8788cec..271029b 100644
--- a/ndn-cpp/c/encoding/binary-xml-forwarding-entry.c
+++ b/ndn-cpp/c/encoding/binary-xml-forwarding-entry.c
@@ -15,7 +15,7 @@
     return error;
     
   if ((error = ndn_BinaryXmlEncoder_writeOptionalUDataDTagElement
-      (encoder, ndn_BinaryXml_DTag_Action, forwardingEntry->action, forwardingEntry->actionLength)))
+      (encoder, ndn_BinaryXml_DTag_Action, &forwardingEntry->action)))
     return error;
   if ((error = ndn_encodeBinaryXmlName(&forwardingEntry->prefix, encoder)))
     return error;
@@ -46,7 +46,7 @@
     return error;
     
   if ((error = ndn_BinaryXmlDecoder_readOptionalUDataDTagElement
-      (decoder, ndn_BinaryXml_DTag_Action, &forwardingEntry->action, &forwardingEntry->actionLength)))
+      (decoder, ndn_BinaryXml_DTag_Action, &forwardingEntry->action)))
     return error;
   if ((error = ndn_decodeBinaryXmlName(&forwardingEntry->prefix, decoder)))
     return error;
diff --git a/ndn-cpp/c/encoding/binary-xml-interest.c b/ndn-cpp/c/encoding/binary-xml-interest.c
index a43ce3b..48d3fe0 100644
--- a/ndn-cpp/c/encoding/binary-xml-interest.c
+++ b/ndn-cpp/c/encoding/binary-xml-interest.c
@@ -26,8 +26,7 @@
     struct ndn_ExcludeEntry *entry = &exclude->entries[i];
     
     if (entry->type == ndn_Exclude_COMPONENT) {
-      if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-          (encoder, ndn_BinaryXml_DTag_Component, entry->component.value, entry->component.valueLength)))
+      if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement(encoder, ndn_BinaryXml_DTag_Component, &entry->component.value)))
         return error;
     }
     else if (entry->type == ndn_Exclude_ANY) {
@@ -60,15 +59,14 @@
       return error;    
     if (gotExpectedTag) {
       // Component
-      uint8_t *component;
-      size_t componentLen;
-      if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(decoder, ndn_BinaryXml_DTag_Component, 0, &component, &componentLen)))
+      struct ndn_Blob component;
+      if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(decoder, ndn_BinaryXml_DTag_Component, 0, &component)))
         return error;
     
       // Add the component entry.
       if (exclude->nEntries >= exclude->maxEntries)
         return NDN_ERROR_read_an_entry_past_the_maximum_number_of_entries_allowed_in_the_exclude;
-      ndn_ExcludeEntry_initialize(exclude->entries + exclude->nEntries, ndn_Exclude_COMPONENT, component, componentLen);
+      ndn_ExcludeEntry_initialize(exclude->entries + exclude->nEntries, ndn_Exclude_COMPONENT, component.value, component.length);
       ++exclude->nEntries;
 
       continue;
@@ -96,9 +94,8 @@
       return error;    
     if (gotExpectedTag) {
       // Skip the Bloom and treat it as Any.
-      uint8_t *value;
-      size_t valueLen;
-      if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(decoder, ndn_BinaryXml_DTag_Bloom, 0, &value, &valueLen)))
+      struct ndn_Blob value;
+      if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(decoder, ndn_BinaryXml_DTag_Bloom, 0, &value)))
         return error;
     
       // Add the any entry.
@@ -160,8 +157,7 @@
       (encoder, ndn_BinaryXml_DTag_InterestLifetime, interest->interestLifetimeMilliseconds)))
     return error;
   
-  if ((error = ndn_BinaryXmlEncoder_writeOptionalBlobDTagElement
-      (encoder, ndn_BinaryXml_DTag_Nonce, interest->nonce, interest->nonceLength)))
+  if ((error = ndn_BinaryXmlEncoder_writeOptionalBlobDTagElement(encoder, ndn_BinaryXml_DTag_Nonce, &interest->nonce)))
     return error;
   
   if ((error = ndn_BinaryXmlEncoder_writeElementClose(encoder)))
@@ -214,7 +210,7 @@
     return error;
   
   if ((error = ndn_BinaryXmlDecoder_readOptionalBinaryDTagElement
-      (decoder, ndn_BinaryXml_DTag_Nonce, 0, &interest->nonce, &interest->nonceLength)))
+      (decoder, ndn_BinaryXml_DTag_Nonce, 0, &interest->nonce)))
     return error;
 
   if ((error = ndn_BinaryXmlDecoder_readElementClose(decoder)))
diff --git a/ndn-cpp/c/encoding/binary-xml-key.c b/ndn-cpp/c/encoding/binary-xml-key.c
index 5ae3db0..d9cce61 100644
--- a/ndn-cpp/c/encoding/binary-xml-key.c
+++ b/ndn-cpp/c/encoding/binary-xml-key.c
@@ -18,7 +18,7 @@
   if (gotExpectedTag) {
     keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST;
     if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
-        (decoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
+        (decoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, 0, &keyLocator->keyData)))
       return error;
   }
   else {
@@ -27,7 +27,7 @@
     if (gotExpectedTag) {
       keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST;
       if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
-          (decoder, ndn_BinaryXml_DTag_PublisherCertificateDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
+          (decoder, ndn_BinaryXml_DTag_PublisherCertificateDigest, 0, &keyLocator->keyData)))
         return error;
     }
     else {
@@ -36,7 +36,7 @@
       if (gotExpectedTag) {
         keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST;
         if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
-            (decoder, ndn_BinaryXml_DTag_PublisherIssuerKeyDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
+            (decoder, ndn_BinaryXml_DTag_PublisherIssuerKeyDigest, 0, &keyLocator->keyData)))
           return error;
       }
       else {
@@ -45,13 +45,13 @@
         if (gotExpectedTag) {
           keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST;
           if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
-              (decoder, ndn_BinaryXml_DTag_PublisherIssuerCertificateDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
+              (decoder, ndn_BinaryXml_DTag_PublisherIssuerCertificateDigest, 0, &keyLocator->keyData)))
             return error;
         }
         else {
           // Key name data is omitted.
           keyLocator->keyNameType = -1;
-          keyLocator->keyDataLength = 0;
+          keyLocator->keyData.length = 0;
         }
       }
     }
@@ -70,13 +70,11 @@
     return error;
 
   if (keyLocator->type == ndn_KeyLocatorType_KEY) {
-    if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-        (encoder, ndn_BinaryXml_DTag_Key, keyLocator->keyData, keyLocator->keyDataLength)))
+    if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement(encoder, ndn_BinaryXml_DTag_Key, &keyLocator->keyData)))
       return error;    
   }
   else if (keyLocator->type == ndn_KeyLocatorType_CERTIFICATE) {
-    if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-        (encoder, ndn_BinaryXml_DTag_Certificate, keyLocator->keyData, keyLocator->keyDataLength)))
+    if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement(encoder, ndn_BinaryXml_DTag_Certificate, &keyLocator->keyData)))
       return error;    
   }
   else if (keyLocator->type == ndn_KeyLocatorType_KEYNAME) {
@@ -85,25 +83,25 @@
     if ((error = ndn_encodeBinaryXmlName(&keyLocator->keyName, encoder)))
       return error;
     
-    if ((int)keyLocator->keyNameType >= 0 && keyLocator->keyDataLength > 0) {
+    if ((int)keyLocator->keyNameType >= 0 && keyLocator->keyData.length > 0) {
       if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST) {
         if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-            (encoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, keyLocator->keyData, keyLocator->keyDataLength)))
+            (encoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, &keyLocator->keyData)))
           return error;    
       }
       else if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST) {
         if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-            (encoder, ndn_BinaryXml_DTag_PublisherCertificateDigest, keyLocator->keyData, keyLocator->keyDataLength)))
+            (encoder, ndn_BinaryXml_DTag_PublisherCertificateDigest, &keyLocator->keyData)))
           return error;    
       }
       else if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST) {
         if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-            (encoder, ndn_BinaryXml_DTag_PublisherIssuerKeyDigest, keyLocator->keyData, keyLocator->keyDataLength)))
+            (encoder, ndn_BinaryXml_DTag_PublisherIssuerKeyDigest, &keyLocator->keyData)))
           return error;    
       }
       else if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST) {
         if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-            (encoder, ndn_BinaryXml_DTag_PublisherIssuerCertificateDigest, keyLocator->keyData, keyLocator->keyDataLength)))
+            (encoder, ndn_BinaryXml_DTag_PublisherIssuerCertificateDigest, &keyLocator->keyData)))
           return error;    
       }
       else
@@ -134,8 +132,7 @@
   if (gotExpectedTag) {
     keyLocator->type = ndn_KeyLocatorType_KEY;
     
-    if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
-        (decoder, ndn_BinaryXml_DTag_Key, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
+    if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(decoder, ndn_BinaryXml_DTag_Key, 0, &keyLocator->keyData)))
       return error;
   }
   else {
@@ -145,7 +142,7 @@
       keyLocator->type = ndn_KeyLocatorType_CERTIFICATE;
     
       if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
-          (decoder, ndn_BinaryXml_DTag_Certificate, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
+          (decoder, ndn_BinaryXml_DTag_Certificate, 0, &keyLocator->keyData)))
         return error;
     }
     else {
diff --git a/ndn-cpp/c/encoding/binary-xml-name.c b/ndn-cpp/c/encoding/binary-xml-name.c
index 00f5858..30cd60f 100644
--- a/ndn-cpp/c/encoding/binary-xml-name.c
+++ b/ndn-cpp/c/encoding/binary-xml-name.c
@@ -17,8 +17,7 @@
   
   size_t i;
   for (i = 0; i < name->nComponents; ++i) {
-    if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-        (encoder, ndn_BinaryXml_DTag_Component, name->components[i].value, name->components[i].valueLength)))
+    if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement(encoder, ndn_BinaryXml_DTag_Component, &name->components[i].value)))
       return error;
   }
   
@@ -44,15 +43,14 @@
       // No more components.
       break;
     
-    uint8_t *component;
-    size_t componentLen;
-    if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(decoder, ndn_BinaryXml_DTag_Component, 0, &component, &componentLen)))
+    struct ndn_Blob component;
+    if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(decoder, ndn_BinaryXml_DTag_Component, 0, &component)))
       return error;
     
     // Add the component to the name.
     if (name->nComponents >= name->maxComponents)
       return NDN_ERROR_read_a_component_past_the_maximum_number_of_components_allowed_in_the_name;
-    ndn_NameComponent_initialize(name->components + name->nComponents, component, componentLen);
+    ndn_NameComponent_initialize(name->components + name->nComponents, component.value, component.length);
     ++name->nComponents;
   }
   
diff --git a/ndn-cpp/c/encoding/binary-xml-publisher-public-key-digest.c b/ndn-cpp/c/encoding/binary-xml-publisher-public-key-digest.c
index 37015bc..4748147 100644
--- a/ndn-cpp/c/encoding/binary-xml-publisher-public-key-digest.c
+++ b/ndn-cpp/c/encoding/binary-xml-publisher-public-key-digest.c
@@ -11,13 +11,12 @@
 ndn_Error ndn_encodeBinaryXmlPublisherPublicKeyDigest
   (struct ndn_PublisherPublicKeyDigest *publisherPublicKeyDigest, struct ndn_BinaryXmlEncoder *encoder)
 {  
-  if (!publisherPublicKeyDigest->publisherPublicKeyDigest || publisherPublicKeyDigest->publisherPublicKeyDigestLength == 0)
+  if (!publisherPublicKeyDigest->publisherPublicKeyDigest.value || publisherPublicKeyDigest->publisherPublicKeyDigest.length == 0)
     return NDN_ERROR_success;
   
   ndn_Error error;
   if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
-      (encoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, publisherPublicKeyDigest->publisherPublicKeyDigest, 
-       publisherPublicKeyDigest->publisherPublicKeyDigestLength)))
+      (encoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, &publisherPublicKeyDigest->publisherPublicKeyDigest)))
     return error;
   
   return NDN_ERROR_success;
@@ -28,8 +27,7 @@
 {
   ndn_Error error; 
   if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
-      (decoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, 0, &publisherPublicKeyDigest->publisherPublicKeyDigest,
-       &publisherPublicKeyDigest->publisherPublicKeyDigestLength)))
+      (decoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, 0, &publisherPublicKeyDigest->publisherPublicKeyDigest)))
     return error;
   
   return NDN_ERROR_success;
@@ -47,8 +45,8 @@
       return error;
   }
   else {
-    publisherPublicKeyDigest->publisherPublicKeyDigest = 0;
-    publisherPublicKeyDigest->publisherPublicKeyDigestLength = 0;
+    publisherPublicKeyDigest->publisherPublicKeyDigest.value = 0;
+    publisherPublicKeyDigest->publisherPublicKeyDigest.length = 0;
   }
   
   return NDN_ERROR_success;
diff --git a/ndn-cpp/c/forwarding-entry.h b/ndn-cpp/c/forwarding-entry.h
index 8fbfaa2..001fabc 100644
--- a/ndn-cpp/c/forwarding-entry.h
+++ b/ndn-cpp/c/forwarding-entry.h
@@ -31,8 +31,7 @@
  * An ndn_ForwardingEntry holds fields for a ForwardingEntry which is used to register a prefix with a hub.
  */
 struct ndn_ForwardingEntry {
-  uint8_t *action;     /**< pointer to pre-allocated buffer.  0 for none. */
-  size_t actionLength; /**< length of action.  0 for none. */
+  struct ndn_Blob action;   /**< A Blob whose value is a pointer to a pre-allocated buffer.  0 for none. */
   struct ndn_Name prefix;
   struct ndn_PublisherPublicKeyDigest publisherPublicKeyDigest;
   int faceId;               /**< -1 for none. */
@@ -50,8 +49,7 @@
 static inline void ndn_ForwardingEntry_initialize
   (struct ndn_ForwardingEntry *self, struct ndn_NameComponent *prefixNameComponents, size_t maxPrefixNameComponents) 
 {
-  self->action = 0;
-  self->actionLength = 0;
+  ndn_Blob_initialize(&self->action, 0, 0);
   ndn_Name_initialize(&self->prefix, prefixNameComponents, maxPrefixNameComponents);
   ndn_PublisherPublicKeyDigest_initialize(&self->publisherPublicKeyDigest);
   self->faceId = -1;
diff --git a/ndn-cpp/c/interest.c b/ndn-cpp/c/interest.c
index 0e32368..44c3ff6 100644
--- a/ndn-cpp/c/interest.c
+++ b/ndn-cpp/c/interest.c
@@ -9,13 +9,13 @@
 
 int ndn_Exclude_compareComponents(struct ndn_NameComponent *component1, struct ndn_NameComponent *component2)
 {
-  if (component1->valueLength < component2->valueLength)
+  if (component1->value.length < component2->value.length)
     return -1;
-  if (component1->valueLength > component2->valueLength)
+  if (component1->value.length > component2->value.length)
     return 1;
 
   // The components are equal length.  Just do a byte compare.  
-  return ndn_memcmp(component1->value, component2->value, component1->valueLength);
+  return ndn_memcmp(component1->value.value, component2->value.value, component1->value.length);
 }
 
 int ndn_Exclude_matches(struct ndn_Exclude *self, struct ndn_NameComponent *component)
diff --git a/ndn-cpp/c/interest.h b/ndn-cpp/c/interest.h
index 801466a..69428ac 100644
--- a/ndn-cpp/c/interest.h
+++ b/ndn-cpp/c/interest.h
@@ -104,8 +104,7 @@
   int answerOriginKind;     /**< -1 for none */
   int scope;                /**< -1 for none */
   double interestLifetimeMilliseconds; /**< milliseconds. -1.0 for none */
-  uint8_t *nonce;           /**< pointer to pre-allocated buffer.  0 for none */
-  size_t nonceLength;       /**< length of nonce.  0 for none */
+  struct ndn_Blob nonce;    /**< The blob whose value is a pointer to a pre-allocated buffer.  0 for none */
 };
 
 /**
@@ -130,8 +129,7 @@
   self->answerOriginKind = -1;
   self->scope = -1;
   self->interestLifetimeMilliseconds = -1.0;
-  self->nonce = 0;
-  self->nonceLength = 0;
+  ndn_Blob_initialize(&self->nonce, 0, 0);
 }
 
 /**
diff --git a/ndn-cpp/c/key.h b/ndn-cpp/c/key.h
index 814c200..a933489 100644
--- a/ndn-cpp/c/key.h
+++ b/ndn-cpp/c/key.h
@@ -31,7 +31,7 @@
  */
 struct ndn_KeyLocator {
   ndn_KeyLocatorType type;     /**< -1 for none */
-  uint8_t *keyData;            /**< A pointer to a pre-allocated buffer for the key data as follows:
+  struct ndn_Blob keyData;            /**< A Blob whose value is a pointer to a pre-allocated buffer for the key data as follows:
     *   If type is ndn_KeyLocatorType_KEY, the key data.
     *   If type is ndn_KeyLocatorType_CERTIFICATE, the certificate data. 
     *   If type is ndn_KeyLocatorType_KEYNAME and keyNameType is ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST, the publisher public key digest. 
@@ -39,7 +39,6 @@
     *   If type is ndn_KeyLocatorType_KEYNAME and keyNameType is ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST, the publisher issuer key digest. 
     *   If type is ndn_KeyLocatorType_KEYNAME and keyNameType is ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST, the publisher issuer certificate digest. 
     */
-  size_t keyDataLength;        /**< The length of keyData. */
   struct ndn_Name keyName;     /**< The key name (only used if type is ndn_KeyLocatorType_KEYNAME.) */
   ndn_KeyNameType keyNameType; /**< The type of data for keyName, -1 for none. (only used if type is ndn_KeyLocatorType_KEYNAME.) */
 };
@@ -53,8 +52,7 @@
 static inline void ndn_KeyLocator_initialize
   (struct ndn_KeyLocator *self, struct ndn_NameComponent *keyNameComponents, size_t maxKeyNameComponents) {
   self->type = (ndn_KeyLocatorType)-1;
-  self->keyData = 0;
-  self->keyDataLength = 0;
+  ndn_Blob_initialize(&self->keyData, 0, 0);
   ndn_Name_initialize(&self->keyName, keyNameComponents, maxKeyNameComponents);
   self->keyNameType = (ndn_KeyNameType)-1;
 }
diff --git a/ndn-cpp/c/name.c b/ndn-cpp/c/name.c
index ab190ce..a81fbb3 100644
--- a/ndn-cpp/c/name.c
+++ b/ndn-cpp/c/name.c
@@ -19,8 +19,8 @@
     struct ndn_NameComponent *selfComponent = self->components + i;
     struct ndn_NameComponent *nameComponent = name->components + i;
 
-    if (selfComponent->valueLength != nameComponent->valueLength ||
-        ndn_memcmp(selfComponent->value, nameComponent->value, selfComponent->valueLength) != 0)
+    if (selfComponent->value.length != nameComponent->value.length ||
+        ndn_memcmp(selfComponent->value.value, nameComponent->value.value, selfComponent->value.length) != 0)
       return 0;
   }
 
diff --git a/ndn-cpp/c/name.h b/ndn-cpp/c/name.h
index 9a4159b..544e3ca 100644
--- a/ndn-cpp/c/name.h
+++ b/ndn-cpp/c/name.h
@@ -7,6 +7,8 @@
 #ifndef NDN_NAME_H
 #define NDN_NAME_H
 
+#include "util/blob.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -15,8 +17,7 @@
  * An ndn_NameComponent holds a pointer to the component value.
  */
 struct ndn_NameComponent {
-  uint8_t *value;     /**< pointer to the pre-allocated buffer for the component value */
-  size_t valueLength; /**< the number of bytes in value */
+  struct ndn_Blob value;     /**< A Blob with a pointer to the pre-allocated buffer for the component value */
 };
 
 /**
@@ -27,8 +28,7 @@
  */
 static inline void ndn_NameComponent_initialize(struct ndn_NameComponent *self, uint8_t *value, size_t valueLength) 
 {
-  self->value = value;
-  self->valueLength = valueLength;
+  ndn_Blob_initialize(&self->value, value, valueLength);
 }
   
 /**
diff --git a/ndn-cpp/c/publisher-public-key-digest.h b/ndn-cpp/c/publisher-public-key-digest.h
index 11d9dec..85891bf 100644
--- a/ndn-cpp/c/publisher-public-key-digest.h
+++ b/ndn-cpp/c/publisher-public-key-digest.h
@@ -8,6 +8,7 @@
 #define NDN_PUBLISHERPUBLICKEYDIGEST_H
 
 #include "common.h"
+#include "util/blob.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -18,8 +19,7 @@
  * We make a separate struct since this is used by multiple other structs.
  */
 struct ndn_PublisherPublicKeyDigest {
-  uint8_t *publisherPublicKeyDigest;      /**< pointer to pre-allocated buffer.  0 for none */
-  size_t publisherPublicKeyDigestLength;  /**< length of publisherPublicKeyDigest.  0 for none */  
+  struct ndn_Blob publisherPublicKeyDigest; /**< A Blob whose value is a pointer to pre-allocated buffer.  0 for none */
 };
 
 /**
@@ -27,8 +27,7 @@
  */
 static inline void ndn_PublisherPublicKeyDigest_initialize(struct ndn_PublisherPublicKeyDigest *self)
 {
-  self->publisherPublicKeyDigest = 0;
-  self->publisherPublicKeyDigestLength = 0;
+  ndn_Blob_initialize(&self->publisherPublicKeyDigest, 0, 0);
 }
 
 #ifdef __cplusplus
diff --git a/ndn-cpp/c/util/blob.h b/ndn-cpp/c/util/blob.h
index 1029185..06dbce1 100644
--- a/ndn-cpp/c/util/blob.h
+++ b/ndn-cpp/c/util/blob.h
@@ -15,20 +15,20 @@
  * An ndn_Blob holds a pointer to a read-only pre-allocated buffer and its length.
  */
 struct ndn_Blob {
-  uint8_t *value;     /**< pointer to the pre-allocated buffer for the value. Must be treated as read only. */
-  size_t valueLength; /**< the number of bytes in value. */
+  uint8_t *value; /**< pointer to the pre-allocated buffer for the value. Must be treated as read only. */
+  size_t length;  /**< the number of bytes in value. */
 };
 
 /**
  * Initialize the ndn_Blob struct with the given value.
  * @param self pointer to the ndn_Blob struct.
  * @param value The pre-allocated buffer for the value, or 0 for none.
- * @param valueLength The number of bytes in value.
+ * @param length The number of bytes in value.
  */
-static inline void ndn_Blob_initialize(struct ndn_Blob *self, uint8_t *value, size_t valueLength) 
+static inline void ndn_Blob_initialize(struct ndn_Blob *self, uint8_t *value, size_t length) 
 {
   self->value = value;
-  self->valueLength = valueLength;
+  self->length = length;
 }
 
 #ifdef	__cplusplus
diff --git a/ndn-cpp/data.cpp b/ndn-cpp/data.cpp
index 1be361a..98ffde0 100644
--- a/ndn-cpp/data.cpp
+++ b/ndn-cpp/data.cpp
@@ -31,7 +31,7 @@
   timestampMilliseconds_ = metaInfoStruct.timestampMilliseconds;
   type_ = metaInfoStruct.type;
   freshnessSeconds_ = metaInfoStruct.freshnessSeconds;
-  finalBlockID_ = Name::Component(Blob(metaInfoStruct.finalBlockID.value, metaInfoStruct.finalBlockID.valueLength));
+  finalBlockID_ = Name::Component(Blob(metaInfoStruct.finalBlockID.value));
 }
 
 Data::Data()
@@ -50,12 +50,7 @@
   signature_->get(dataStruct.signature);
   name_.get(dataStruct.name);
   metaInfo_.get(dataStruct.metaInfo);
-  
-  dataStruct.contentLength = content_.size();
-  if (content_.size() > 0)
-    dataStruct.content = (uint8_t*)content_.buf();
-  else
-    dataStruct.content = 0;
+  content_.get(dataStruct.content);
 }
 
 void 
@@ -64,7 +59,7 @@
   signature_->set(dataStruct.signature);
   name_.set(dataStruct.name);
   metaInfo_.set(dataStruct.metaInfo);
-  content_ = Blob(dataStruct.content, dataStruct.contentLength);
+  content_ = Blob(dataStruct.content);
 
   onChanged();
 }
diff --git a/ndn-cpp/forwarding-entry.cpp b/ndn-cpp/forwarding-entry.cpp
index 57c01c4..93c4d26 100644
--- a/ndn-cpp/forwarding-entry.cpp
+++ b/ndn-cpp/forwarding-entry.cpp
@@ -15,8 +15,8 @@
 void 
 ForwardingEntry::set(const struct ndn_ForwardingEntry& forwardingEntryStruct) 
 {
-  if (forwardingEntryStruct.action && forwardingEntryStruct.actionLength > 0)
-    action_ = string(forwardingEntryStruct.action, forwardingEntryStruct.action + forwardingEntryStruct.actionLength);
+  if (forwardingEntryStruct.action.value && forwardingEntryStruct.action.length > 0)
+    action_ = string(forwardingEntryStruct.action.value, forwardingEntryStruct.action.value + forwardingEntryStruct.action.length);
   else
     action_ = "";
             
@@ -36,11 +36,11 @@
   forwardingEntryStruct.forwardingFlags = forwardingFlags_;
   forwardingEntryStruct.freshnessSeconds = freshnessSeconds_;
 
-  forwardingEntryStruct.actionLength = action_.size();
+  forwardingEntryStruct.action.length = action_.size();
   if (action_.size() > 0)
-    forwardingEntryStruct.action = (uint8_t *)&action_[0];
+    forwardingEntryStruct.action.value = (uint8_t *)&action_[0];
   else
-    forwardingEntryStruct.action = 0;
+    forwardingEntryStruct.action.value = 0;
 }
 
 }
diff --git a/ndn-cpp/interest.cpp b/ndn-cpp/interest.cpp
index dff002c..e1a6af7 100644
--- a/ndn-cpp/interest.cpp
+++ b/ndn-cpp/interest.cpp
@@ -31,7 +31,7 @@
     ndn_ExcludeEntry *entry = &excludeStruct.entries[i];
     
     if (entry->type == ndn_Exclude_COMPONENT)
-      addComponent(entry->component.value, entry->component.valueLength);
+      addComponent(entry->component.value.value, entry->component.value.length);
     else if (entry->type == ndn_Exclude_ANY)
       addAny();
     else
@@ -73,7 +73,7 @@
   answerOriginKind_ = interestStruct.answerOriginKind;
   scope_ = interestStruct.scope;
   interestLifetimeMilliseconds_ = interestStruct.interestLifetimeMilliseconds;
-  nonce_ = Blob(interestStruct.nonce, interestStruct.nonceLength);
+  nonce_ = Blob(interestStruct.nonce);
 }
 
 void 
@@ -88,12 +88,7 @@
   interestStruct.answerOriginKind = answerOriginKind_;
   interestStruct.scope = scope_;
   interestStruct.interestLifetimeMilliseconds = interestLifetimeMilliseconds_;
-
-  interestStruct.nonceLength = nonce_.size();
-  if (nonce_.size() > 0)
-    interestStruct.nonce = (uint8_t *)nonce_.buf();
-  else
-    interestStruct.nonce = 0;
+  nonce_.get(interestStruct.nonce);
 }
   
 }
diff --git a/ndn-cpp/key.cpp b/ndn-cpp/key.cpp
index ef57265..db3ea58 100644
--- a/ndn-cpp/key.cpp
+++ b/ndn-cpp/key.cpp
@@ -15,13 +15,7 @@
 KeyLocator::get(struct ndn_KeyLocator& keyLocatorStruct) const 
 {
   keyLocatorStruct.type = type_;
-  
-  keyLocatorStruct.keyDataLength = keyData_.size();
-  if (keyData_.size() > 0)
-    keyLocatorStruct.keyData = (uint8_t *)keyData_.buf();
-  else
-    keyLocatorStruct.keyData = 0;
-
+  keyData_.get(keyLocatorStruct.keyData);
   keyName_.get(keyLocatorStruct.keyName);
   keyLocatorStruct.keyNameType = keyNameType_;
 }
@@ -30,7 +24,7 @@
 KeyLocator::set(const struct ndn_KeyLocator& keyLocatorStruct)
 {
   type_ = keyLocatorStruct.type;
-  keyData_ = Blob(keyLocatorStruct.keyData, keyLocatorStruct.keyDataLength);
+  keyData_ = Blob(keyLocatorStruct.keyData);
   if (keyLocatorStruct.type == ndn_KeyLocatorType_KEYNAME) {
     keyName_.set(keyLocatorStruct.keyName);
     keyNameType_ = keyLocatorStruct.keyNameType;
diff --git a/ndn-cpp/name.cpp b/ndn-cpp/name.cpp
index 40dbab5..d8174e6 100644
--- a/ndn-cpp/name.cpp
+++ b/ndn-cpp/name.cpp
@@ -221,7 +221,7 @@
 {
   clear();
   for (size_t i = 0; i < nameStruct.nComponents; ++i)
-    addComponent(nameStruct.components[i].value, nameStruct.components[i].valueLength);  
+    addComponent(nameStruct.components[i].value.value, nameStruct.components[i].value.length);  
 }
 
 Name&
diff --git a/ndn-cpp/name.hpp b/ndn-cpp/name.hpp
index 0fe7284..d589c89 100644
--- a/ndn-cpp/name.hpp
+++ b/ndn-cpp/name.hpp
@@ -68,11 +68,7 @@
     void 
     get(struct ndn_NameComponent& componentStruct) const 
     {
-      componentStruct.valueLength = value_.size(); 
-      if (value_.size() > 0)
-        componentStruct.value = (uint8_t*)value_.buf();
-      else
-        componentStruct.value = 0;
+      value_.get(componentStruct.value);
     }
   
     const Blob& 
diff --git a/ndn-cpp/publisher-public-key-digest.hpp b/ndn-cpp/publisher-public-key-digest.hpp
index 1c04b3a..8069fa0 100644
--- a/ndn-cpp/publisher-public-key-digest.hpp
+++ b/ndn-cpp/publisher-public-key-digest.hpp
@@ -30,11 +30,7 @@
   void 
   get(struct ndn_PublisherPublicKeyDigest& publisherPublicKeyDigestStruct) const 
   {
-    publisherPublicKeyDigestStruct.publisherPublicKeyDigestLength = publisherPublicKeyDigest_.size();
-    if (publisherPublicKeyDigest_.size() > 0)
-      publisherPublicKeyDigestStruct.publisherPublicKeyDigest = (uint8_t *)publisherPublicKeyDigest_.buf();
-    else
-      publisherPublicKeyDigestStruct.publisherPublicKeyDigest = 0;
+    publisherPublicKeyDigest_.get(publisherPublicKeyDigestStruct.publisherPublicKeyDigest);
   }
   
   /**
@@ -44,8 +40,7 @@
   void 
   set(const struct ndn_PublisherPublicKeyDigest& publisherPublicKeyDigestStruct) 
   {
-    publisherPublicKeyDigest_ = 
-      Blob(publisherPublicKeyDigestStruct.publisherPublicKeyDigest, publisherPublicKeyDigestStruct.publisherPublicKeyDigestLength);
+    publisherPublicKeyDigest_ = Blob(publisherPublicKeyDigestStruct.publisherPublicKeyDigest);
   }
 
   const Blob& 
diff --git a/ndn-cpp/sha256-with-rsa-signature.cpp b/ndn-cpp/sha256-with-rsa-signature.cpp
index 5862faa..3153551 100644
--- a/ndn-cpp/sha256-with-rsa-signature.cpp
+++ b/ndn-cpp/sha256-with-rsa-signature.cpp
@@ -20,24 +20,9 @@
 void 
 Sha256WithRsaSignature::get(struct ndn_Signature& signatureStruct) const 
 {
-  signatureStruct.digestAlgorithmLength = digestAlgorithm_.size();
-  if (digestAlgorithm_.size() > 0)
-    signatureStruct.digestAlgorithm = (uint8_t *)digestAlgorithm_.buf();
-  else
-    signatureStruct.digestAlgorithm = 0;
-
-  signatureStruct.witnessLength = witness_.size();
-  if (witness_.size() > 0)
-    signatureStruct.witness = (uint8_t *)witness_.buf();
-  else
-    signatureStruct.witness = 0;
-
-  signatureStruct.signatureLength = signature_.size();
-  if (signature_.size() > 0)
-    signatureStruct.signature = (uint8_t *)signature_.buf();
-  else
-    signatureStruct.signature = 0;
-  
+  digestAlgorithm_.get(signatureStruct.digestAlgorithm);
+  witness_.get(signatureStruct.witness);
+  signature_.get(signatureStruct.signature);  
   publisherPublicKeyDigest_.get(signatureStruct.publisherPublicKeyDigest);
   keyLocator_.get(signatureStruct.keyLocator);
 }
@@ -45,9 +30,9 @@
 void 
 Sha256WithRsaSignature::set(const struct ndn_Signature& signatureStruct)
 {
-  digestAlgorithm_ = Blob(signatureStruct.digestAlgorithm, signatureStruct.digestAlgorithmLength);
-  witness_ = Blob(signatureStruct.witness, signatureStruct.witnessLength);
-  signature_ = Blob(signatureStruct.signature, signatureStruct.signatureLength);
+  digestAlgorithm_ = Blob(signatureStruct.digestAlgorithm);
+  witness_ = Blob(signatureStruct.witness);
+  signature_ = Blob(signatureStruct.signature);
   publisherPublicKeyDigest_.set(signatureStruct.publisherPublicKeyDigest);
   keyLocator_.set(signatureStruct.keyLocator);
 }
diff --git a/ndn-cpp/util/blob.hpp b/ndn-cpp/util/blob.hpp
index ef13433..2c238a6 100644
--- a/ndn-cpp/util/blob.hpp
+++ b/ndn-cpp/util/blob.hpp
@@ -8,6 +8,7 @@
 #define	NDN_BLOB_HPP
 
 #include "../common.hpp"
+#include "../c/util/blob.h"
 
 namespace ndn {
 
@@ -52,6 +53,15 @@
   }
   
   /**
+   * Create a new Blob with an immutable copy of the array in the given Blob struct.
+   * @param blobStruct The C ndn_Blob struct to receive the pointer.
+   */
+  Blob(const struct ndn_Blob& blobStruct)
+  : ptr_lib::shared_ptr<const std::vector<uint8_t> >(new std::vector<uint8_t>(blobStruct.value, blobStruct.value + blobStruct.length))
+  {
+  }
+  
+  /**
    * Create a new Blob to point to an existing byte array.  IMPORTANT: After calling this constructor,
    * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
    * @param value A pointer to a vector with the byte array.  This takes another reference and does not copy the bytes.
@@ -88,6 +98,21 @@
     else
       return 0;
   }
+  
+  /**
+   * Set the blobStruct to point to this Blob's byte array, without copying any memory.
+   * WARNING: The resulting pointer in blobStruct is invalid after a further use of this object which could reallocate memory.
+   * @param blobStruct The C ndn_Blob struct to receive the pointer.
+   */
+  void 
+  get(struct ndn_Blob& blobStruct) const 
+  {
+    blobStruct.length = size(); 
+    if (size() > 0)
+      blobStruct.value = (uint8_t*)buf();
+    else
+      blobStruct.value = 0;
+  }
 };
 
 }