Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Quickest way from BSTR to char * (no mfc)

Posted on 2001-06-13
20
Medium Priority
?
1,436 Views
Last Modified: 2013-11-25
Using ATL alone, what is the quickest way to convert a BSTR * to/from a char * ?

I want to pass a BSTR * as a parameter, and also return them.

Eg.
[id(3)] HRESULT Test_String([in] BSTR* szInString, [out, retval] BSTR *szRetval);

I'm using strtok internally, so unless there's a BSTR equivalent, then I need to use char *.  Any thoughts?
0
Comment
Question by:InetMatt
[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
  • 4
  • 4
  • 2
  • +9
20 Comments
 
LVL 2

Expert Comment

by:GloriousRain
ID: 6189429
BSTR bstrText("Sample");
char lpText[256];
strcpy(lpText, (LPSTR)_bstr_t(bstrText));
0
 

Expert Comment

by:RanganathanVenkatakrishnan
ID: 6189433
1. VarI1FromStr
This function converts variant data types to char from BSTR.

2. VarBstrFromI1
This function converts variant data types to BSTR from char.

// I hope this solves your problem.

0
 
LVL 2

Expert Comment

by:GloriousRain
ID: 6189443
oop, _bstr_t bstrText("Sample") instead of BSTR bstrText("Sample")
0
Independent Software Vendors: 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!

 

Author Comment

by:InetMatt
ID: 6189465
Ok, that's great, but I think I need code samples.  I've found heaps of little bits that almost do the job, but failures are really annoying me.
0
 

Author Comment

by:InetMatt
ID: 6189471
What I've noticed is that there are about a billion ways to do this, and I want to find the easiest and most efficient way of doing this.  
0
 

Author Comment

by:InetMatt
ID: 6189472
A little more detail please?
0
 
LVL 22

Accepted Solution

by:
ambience earned 225 total points
ID: 6189539
//From TCHAR* to BSTR
bool CAccountInformationImpl::GetUserID(BSTR *pVal)
{
     _bstr_t  tempData ( _T("MY_USER") ); //
     *pVal = tempData.copy();
     return true;
}


// From BSTR to TCHAR*
bool CAccountInformationImpl::SetUserID(BSTR newVal)
{
     // TODO: Add your implementation code here
     _bstr_t  tempData ( newVal, FALSE);
     _tcscpy ( m_UserID, tempData );
     return true;
}

maybe this should help ...
0
 
LVL 22

Expert Comment

by:ambience
ID: 6189544
m_USerID is defined as

TCHAR m_UserID [ 256 ];
0
 

Author Comment

by:InetMatt
ID: 6189857
Are you sure that you have to convert BSTR -> _bstr_t -> TCHAR?  isn't there a quicker way?  

Eg.
BSTR -> TCHAR
0
 

Expert Comment

by:NickAtBOM
ID: 6190039
Use the ALT string conversion macros.

Somewhere in your function, before the conversion you will need the line:

USES_CONVERSION;    // this macro expands up to variable
                    // definitions

Then, to convert to a BSTR from a char use:

strBSTR = A2OLE(strChar);

and to convert back use

strChar = OLE2A(strBSTR);

check out http://msdn.microsoft.com/library/devprods/vs6/visualc/vcmfc/_atl_string_conversion_macros.htm for a full discussion.
0
 
LVL 6

Expert Comment

by:snoegler
ID: 6190141
LPWSTR ToWideString(LPCTSTR lpszSource)
{
#ifndef _UNICODE
  int len;
  LPWSTR lpwszResult = NULL;
  len = MultiByteToWideChar(CP_ACP,0,lpszSourceString,-1,NULL,0);
  lpwszResult = new WCHAR[len+1];
  MultiByteToWideChar(CP_ACP,0,lpszSourceString,-1,lpwszResult,len);
  return lpwResult;
#else
  LPWSTR lpwszResult = new WCHAR[_wcslen(lpszSource)+1];
  _wcscpy(lpwszResult,lpszSource);
  return lpszSource;
#endif
}

LPCTSTR ToTString(LPWSTR lpwszSource)
{
#ifndef _UNICODE
  int lenBytes;
  LPTSTR lpszResult = NULL;
  lenBytes = WideCharToMultiByte(CP_ACP,0,lpwszSource,-1,NULL,0,NULL,NULL);
  lpszResult = new TCHAR[(lenBytes/sizeof(TCHAR))+1];
  WideCharToMultiByte(CP_ACP,0,lpwszSource,-1,lpszResult,lenBytes,NULL,NULL);
  return lpszResult;
#else
  LPWSTR lpwszResult = new WCHAR[_wcslen(lpszSource)+1];
  _wcscpy(lpwszResult,lpszSource);
  return lpszSource;
#endif
}

BSTR ToBSTR(LPCTSTR lpszSource)
{
  LPWSTR lpwszSource = ToWideChar(lpszSource);
  BSTR bstrRes = SysAllocString(lpwszSource);
  delete[] lpwszSource;
  return bstrRes;
}

I hope those work, i didn't try them yet.
Note that you can use ToTString also with a BSTR argument, there is no need for something like BSTRToTString!
0
 
LVL 9

Expert Comment

by:jasonclarke
ID: 6190496
As mentioned before, the _bstr_t is the simplest form to use:

STDMETHODIMP CTest::Test(BSTR istr, BSTR *ostr)
{
    _bstr_t bs(istr);

    const char* s = static_cast<const char*>(bs);

    _bstr_t os(s);

    *ostr = os.copy();

    return S_OK;
}

0
 
LVL 6

Expert Comment

by:snoegler
ID: 6190527
inetmatt Date: 06/14/2001 12:44AM PST
>> Are you sure that you have to convert BSTR -> _bstr_t -> TCHAR?  isn't there a quicker way?  

0
 
LVL 6

Expert Comment

by:snoegler
ID: 6190661
>> there is no need for something like BSTRToTString!
As long as you are using BSTR's not containing '\0' characters, i forgot; but i guess that's not the case here ...
0
 
LVL 6

Expert Comment

by:snoegler
ID: 6190671
If you need it even faster and you don't worry about codepage problems and localization (can be dangerous), you can also convert a TCHAR string to a WCHAR string like this:

LPWSTR lpwszResult = new WCHAR[_tcslen(lpszSource)+1];
int i = 0;
for(int i=0;(lpwszResult[i]=lpszSource[i])!='\0';i++) {};

But you're going to run into problems when it happens that the BSTR really contains unicode characters ...
Converting the WCHAR* to a BSTR can then be done using SysAllocString.
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6190715
> id(3)] HRESULT Test_String([in] BSTR* szInString, [out, retval] BSTR *szRetval);

on an aside this should be (note I removed the * from the [in] parameter)

id(3)] HRESULT Test_String([in] BSTR szInString, [out, retval] BSTR *szRetval);

as to conversions - if you are on NT only then use unicode at all times then you can treat a BSTR as WCHAR for most of the time (but you cannot treat WCHAR as BSTRs) and will require no conversions - so the quickest conversion is no conversion - else if you have to use ansi then use the ATL macros - howver make sure you use the right ones

eg A2OLE does not create BSTR that can be used in COM calls as it is the same as A2W you need to use A2BSTR however you need to be very careful

bad

pMyObj->MyFunc(A2BSTR("data")); // this will leak

good

BSTR bstrData=A2BSTR("data");
pMyObj->MyFunc(bstrData);
::SysFreeString(bstrData);

this is why you will see people use wrapper classes such as CComBSTR and _bstr_t as it save on the typing - however the above is quicker as it does not have to create the CComBSTR (or _bstr_t) object. however even the wrapper classes have bugs due to their dependancies on the ATL classes see KB Q241857


0
 

Expert Comment

by:balugaa
ID: 6192534
I dont thik u can get easier than

#include <comutil.h>

using namespace _com_util
{
BSTR ConvertStringToBSTR(const char* pSrc) throw(_com_error);

     // Convert BSTR to char *
     //
char* __stdcall ConvertBSTRToString(BSTR pSrc) throw(_com_error);
}

these two utility functions work a treat

good luck

....
0
 
LVL 30

Expert Comment

by:Axter
ID: 6192745
InetMatt,

Did you get your answer.  If so please, please award points.
If not, please request specific information.

Thanks
0
 
LVL 11

Expert Comment

by:griessh
ID: 6817334
I think you forgot this question. I will ask Community Support to close it unless you finalize it within 7 days. Unless there is objection or further activity,  I will suggest to accept "ambience" comment(s) as an answer. This was the first answer to solve the problem, it is hard to evaluate the request for a 'quicker way'.

If you think your question was not answered at all, you can post a request in Community support (please include this link) to refund your points.
The link to the Community Support area is: http://www.experts-exchange.com/jsp/qList.jsp?ta=commspt

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
0
 
LVL 5

Expert Comment

by:Netminder
ID: 6833251
Per recommendation comment force/accepted by

Netminder
Community Support Moderator
Experts Exchange
0

Featured Post

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

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

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

715 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