In COM all strings are UNOCODE BSTRs. GB32 converts a string to UNICODE before it calls the set_Tag() function. When the property .Tag is set with a literal string constant, the compiler optimizes string assignment by converting the literal string to an UNICODE string before hand. For instance, the assignment Ocx.Tag = "Hello" is stored as:
Ocx.Tag = "H" #0 "e" #0 "l" #0 "l" #0 "0" #0 #0
When the .Tag property assignment is actually executed during runtime, the UNICODE string is passed to the set_Tag() function of the Ocx/COM object, and the BSTR is stored with the COM object for later access. But something is breaking the process ...
GB32 stores ANSI code
The rationale behind GB32's implementation of UNICODE vs. ANSI isn't very clear. IMHO the most simple, effective, and fastest procedure would be to store the pointer to the UNICODE string as it is passed to the Tag property. But GB32 converts it (back) to ANSI and stores a pointer to the ANSI-string memory. Of course, GB32 strings might be as large as physical memory and storing a UNICODE string doubles the memory necessary. But that couldn't be the reason for this behavior, could it?
Anyway, so far so good. It is a fact of life. If you like you can store binary data in a string and assign it to a .Tag property. But can you get it out of the Tag property? The answer is No! When the BSTR passed to the set_Tag() function is copied to ANSI, GB32 only stores the pointer to the converted ANSI string (a char* in C/C++). It doesn't save the length of the passed BSTR. So, how does GB32 know how many characters to return from get_Tag()? It doesn't and simply invokes a call to the C-library function strlen(char*), which returns at first occurrence of '\0'.
Binary data cannot be stored in a .Tag property.