Solved

BSTR to BYTE problem

Posted on 2004-04-29
2
1,562 Views
Last Modified: 2012-06-21
Hi, I am new to Visual C++, and I am trying to write a simple routine which will convert a BSTR toa BYTE array, perform some operations on the BYTE array, and then return a BSTR to the calling object. I am attempting to make a COM object using the ATL Wizard, and as I understand it, the BSTR data type is what is normally used. I have Visual Studio 6.0 as well as Visual Studio .NET. From what I can tell, the code would probably be the same on either platform, but I could be wrong.

Anyway, here is what I was trying to do, but it doesnt seem to be working. Again, I am new to Visual C++, so my understanding of streams, etc. is all based off of online examples, so the below code may be totally wrong.

STDMETHODIMP Ctest_meth98::testFunction(BSTR inSt1, BSTR* outSt2)
{
      BYTE buf1[1000];
      CComBSTR *in_bs1 = new CComBSTR();
      CComBSTR *out_bs2 = new CComBSTR();
      IStream *p_inS, *p_outS;
      ULONG i, j;
      
      CreateStreamOnHGlobal(NULL, TRUE, &p_inS);
      in_bs1->AppendBSTR(inSt1);
      in_bs1->WriteToStream(p_inS);

/* At this point I assume that the stream would contain the string value passed in to the BSTR in_bs1 */



/* Seek to beginning of stream and try to read 100 bytes into a BYTE buffer */
      p_inS->Seek(tmpi, STREAM_SEEK_SET, NULL);
      p_inS->Read(buf1, 100, &i);


/* Now write this same byte buffer to a second stream. Eventually I will modify this buffer, but I am leaving this
     out for the time being */
      CreateStreamOnHGlobal(NULL, TRUE, &p_outS);
      p_outS->Write(buf1, i, &j);


/* Now take the value of the new stream, and put it into a new CComBSTR object */
      out_bs2->ReadFromStream(p_outS);

/* Append test value */
      out_bs2->Append("test val");


/* Return BSTR to calling object */
      *outSt2 = out_bs2->Detach();
      return S_OK;
}


After making the DLL, registering, and calling from my ASP page, the test function above will always return just "test val", even though I pass it a input parameter as well. Is there an easier way to convert from BSTR to BYTE array? Or is there something wrong with the above code I am using? I plan on buying a book this weekend to help me out, but if anyone could give me any tips before then I would appreciate it. Thanks.
0
Comment
Question by:Jeffbub
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 

Accepted Solution

by:
hanzelko earned 275 total points
ID: 10948306
Hi.

I suppose you must add this after p_outS->Write(buf1, i, &j); :

LARGE_INTEGER li = {0, 0};
p_outS->Seek(li, STREAM_SEEK_SET, NULL);

Just seek to begin of stream and then read.
And it should work.

By the way there is an easy way to get char * or wchar * from BSTR.
and char * is the same as BYTE *.

So.

#include <comdef.h>

BSTR h = ....  (get your BSTR from somewhere)
_bstr_t _h = _bstr_t(h);       // this will create _bstr_t wrapper from BSTR with your BSTR
char *ch = (char *)_h;         // this will return you const char* (so const pointer to one byte chars)

or

wchar_t *ch = (wchar_t *)_h;   // this will return you const wchar_t * (so pointer to two byte chars)


char * extractor is UNICODE safe. It does conversions from UNICODE to ANSI by calling WideCharToMultiByte.

Then you can copy it to some buffer and change it like you want.

And then if you want to return BSTR to outer world. just do:

char *out = "Some bytes";
_bstr_t _ret = _bstr_t(out);      // construct _bstr_t form char * (you can use wchar_t too)
BSTR ret = _ret.copy();           // this will return you copied BSTR from your _bstr_t

and this pointer can be returned to the world outside.

So that's it.








0
 

Author Comment

by:Jeffbub
ID: 10949360
Fantastic! That worked like a charm. Thanks for the well detailed instructions!
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question