InetMatt
asked on
Quickest way from BSTR to char * (no mfc)
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?
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?
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.
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.
oop, _bstr_t bstrText("Sample") instead of BSTR bstrText("Sample")
ASKER
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.
ASKER
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.
ASKER
A little more detail please?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
m_USerID is defined as
TCHAR m_UserID [ 256 ];
TCHAR m_UserID [ 256 ];
ASKER
Are you sure that you have to convert BSTR -> _bstr_t -> TCHAR? isn't there a quicker way?
Eg.
BSTR -> TCHAR
Eg.
BSTR -> TCHAR
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.
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.
LPWSTR ToWideString(LPCTSTR lpszSource)
{
#ifndef _UNICODE
int len;
LPWSTR lpwszResult = NULL;
len = MultiByteToWideChar(CP_ACP ,0,lpszSou rceString, -1,NULL,0) ;
lpwszResult = new WCHAR[len+1];
MultiByteToWideChar(CP_ACP ,0,lpszSou rceString, -1,lpwszRe sult,len);
return lpwResult;
#else
LPWSTR lpwszResult = new WCHAR[_wcslen(lpszSource)+ 1];
_wcscpy(lpwszResult,lpszSo urce);
return lpszSource;
#endif
}
LPCTSTR ToTString(LPWSTR lpwszSource)
{
#ifndef _UNICODE
int lenBytes;
LPTSTR lpszResult = NULL;
lenBytes = WideCharToMultiByte(CP_ACP ,0,lpwszSo urce,-1,NU LL,0,NULL, NULL);
lpszResult = new TCHAR[(lenBytes/sizeof(TCH AR))+1];
WideCharToMultiByte(CP_ACP ,0,lpwszSo urce,-1,lp szResult,l enBytes,NU LL,NULL);
return lpszResult;
#else
LPWSTR lpwszResult = new WCHAR[_wcslen(lpszSource)+ 1];
_wcscpy(lpwszResult,lpszSo urce);
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!
{
#ifndef _UNICODE
int len;
LPWSTR lpwszResult = NULL;
len = MultiByteToWideChar(CP_ACP
lpwszResult = new WCHAR[len+1];
MultiByteToWideChar(CP_ACP
return lpwResult;
#else
LPWSTR lpwszResult = new WCHAR[_wcslen(lpszSource)+
_wcscpy(lpwszResult,lpszSo
return lpszSource;
#endif
}
LPCTSTR ToTString(LPWSTR lpwszSource)
{
#ifndef _UNICODE
int lenBytes;
LPTSTR lpszResult = NULL;
lenBytes = WideCharToMultiByte(CP_ACP
lpszResult = new TCHAR[(lenBytes/sizeof(TCH
WideCharToMultiByte(CP_ACP
return lpszResult;
#else
LPWSTR lpwszResult = new WCHAR[_wcslen(lpszSource)+
_wcscpy(lpwszResult,lpszSo
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!
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;
}
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;
}
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?
>> Are you sure that you have to convert BSTR -> _bstr_t -> TCHAR? isn't there a quicker way?
>> 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 ...
As long as you are using BSTR's not containing '\0' characters, i forgot; but i guess that's not the case here ...
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]=lpszSo urce[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.
LPWSTR lpwszResult = new WCHAR[_tcslen(lpszSource)+
int i = 0;
for(int i=0;(lpwszResult[i]=lpszSo
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.
> 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("dat a")); // 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
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("dat
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
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
....
#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
....
InetMatt,
Did you get your answer. If so please, please award points.
If not, please request specific information.
Thanks
Did you get your answer. If so please, please award points.
If not, please request specific information.
Thanks
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: https://www.experts-exchange.com/jsp/qList.jsp?ta=commspt
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
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: https://www.experts-exchange.com/jsp/qList.jsp?ta=commspt
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
Per recommendation comment force/accepted by
Netminder
Community Support Moderator
Experts Exchange
Netminder
Community Support Moderator
Experts Exchange
char lpText[256];
strcpy(lpText, (LPSTR)_bstr_t(bstrText));