There are many ways of skinning this cat. Here's one:
void myFunction( INchar* name,
OUT char* path)
{
USES_CONVERSION;
MyCOMFunction( CComBSTR(A2COLE(name));
}
For background reading, see:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_atl_string_conversion_macros.asp
(watch for line breaks).
Brian
even better use T2COLE instead of A2COLE http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_atl_string_conversion_macros.asp
> even better use T2COLE instead of A2COLE Why on the earth? He's talking about char *, not TCHAR * nor LPTSTR. He'd get compile errors if he uses T2COLE in an Unicode build. "Experience is a hard teacher: she gives the test first, the lesson afterwards." - Vernon Sanders law
I believe that is new to ATL7, so if you are stuck with ATL3 (VC6) that is
not an option.
However,
void myFunction(IN char* name, OUT char* path)
{
MyCOMFunction(_bstr_t(name));
}
is another way of doing it.
Incidentally, if "path" is truly an "out" parameter then this function
signature looks like a good candidate for a buffer overrun. Either pass a
pointer to a pointer and allocate the storage inside myFunction (COM-style),
making the client responsible for cleaning it up (and so requiring it to
know the means used to allocate it), or pass a size_t cchMax which gives the
maximum number of characters that can be copied into path (and respect it).
S.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_atl_string_conversion_macros.asp
You can just write CComBSTR(name). CComBSTR has a constructor taking
char*
--
With best wishes,
Igor Tandetnik
"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken
Hey everybody,
You're all missing the out parameter. Simon touched on it, and he has a
point in that the char* is really not adequate for out-params. Either add an
extra indirection (char**) and allocate memory inside myFunction, or add a
buffer length parameter as well, indicating how long the buffer pointer to
by 'path' is.
I'd re-do it something like this;
void myFunction(const char* pszName, char* pszPath, unsigned cchPath)
{
CComBSTR strPath;
MyCOMFunction(CComBSTR(pszName), &strPath);
if(strPath.Length() > 0)
{
strncpy(pszPath, OLE2A(strPath), cchPath);
}
else
{
pszPath[0] = 0;
}
}
--
Best regards,
Kim Grman
Well I thought I did more than that :)... anyway, I suppose I should have given an example of the rewrite. Thanks Kim S.
1.Converting BSTR to char or char*
I am creating a com object in which I use the SQL VDI functionality to backup databases. I call the object from VBScript with a WScript.CreateObject function. One of the properties of the object will be the database name. The only property data type I can use per the VC++ wizzard is BSTR. The sql.h files uses datatype char for this parameter. I need to make a convsersion from BSTR to char and vice versa. What is the safest way to do this ? Is there already an inherent function or Macro in C++ to do this ? I am VB programmer so I am very weak in this area. Please let me know if you have any suggestions or ideas.
Hi all, I have a function which takes in BStr type variable and then I need to pass the value to another function which takes in char* variable. Eg. FuncA(char *msg) So How am i going to pass it? The second question will be how am i going to concatanate 2 string into BStr variable? example, a = "Hello" b = "World" so c = "HelloWorld" where c is of type BSTR. Anybody able to help me? Thankx in advance
3.converting char * to BSTR and VARIANT
Hi Everyone, Does anybody know if there a way of converting/casting char * to BSTR and VARIANT with out using CString and if so how? (CString is giving me all sort of LNK errors I can't figure out). Thanks in advance, Lena
4.Convert BSTR HUGEP * to a wchar_t* or char *
Hello I want to be able to convert a pointer that is defined as a BSTR
HUGEP *pbstr to a wchar_t * or a char* pointer but I am having some
issues. First of all I want to make sure I understand BSTR HUGEP * -<
to me this means I have a BSTR pointer that is cable of 64 bit but I'm
not quiet sure . Anyway I have the code working to get the elements
from the safe array but I want to convert the array value to a char *
or a wchar_t in a defined structure before I go back to the calling
program. I can copy pbstr[0] into a wchar_t data[300] but Id rather
use wchar_t * instead and I am concerned that the wcscopy looks right
at the suface but since a BSTR is not a true Wchar_t then this concerns
me as well - Any ideas?
Here is my code
int u_dll_ims21_call(wchar_t *TheConnectString, wchar_t *TheTable,
wchar_t *TheFields, wchar_t *ThePopupTitle, wchar_t *TheOrderBy,
wchar_t *TheWhereClause, wchar_t *ThePosition)
{
// Now we will intilize COM
HRESULT hr = CoInitialize(0);
if(SUCCEEDED(hr))
{
_clsCat16Ptr ptrCat16(__uuidof(clsCat16)); //Smart pointer wrapper
//_clsCat16 *IclsCat16 = NULL;
//hr = CoCreateInstance(__uuidof (clsCat16),
// NULL,
// CLSCTX_INPROC_SERVER,
// _uuidof (_clsCat16),
// (void**) &IclsCat16);
// if(SUCCEEDED(hr))
// {
BSTR bstrTheConnectString= SysAllocString(TheConnectString);
BSTR bstrTheTable = SysAllocString(TheTable);
BSTR bstrTheFields= SysAllocString(TheFields);
BSTR bstrThePopupTitle = SysAllocString(ThePopupTitle);
BSTR bstrTheOrderBy = SysAllocString(TheOrderBy);
BSTR bstrTheWhereClause = SysAllocString(TheWhereClause);
BSTR bstrThePosition = SysAllocString(ThePosition);
//Create a SafeArray
SAFEARRAY FAR* RTNArray = NULL;
// _bstr_t bvalue = ptrCat16->Popup(&bstrTheConnectString,
&bstrTheTable,
// &bstrTheFields, &bstrThePopupTitle,
// &bstrTheOrderBy, &bstrTheWhereClause,
// &bstrThePosition);
short bvalue = ptrCat16->Popup(&bstrTheConnectString, &bstrTheTable,
&bstrTheFields, &bstrThePopupTitle,
&bstrTheOrderBy, &RTNArray, &bstrTheWhereClause,
&bstrThePosition);
if(bvalue == 0)
{
//Free all the bstrings //
SysFreeString(bstrTheConnectString);
SysFreeString(bstrTheTable);
SysFreeString(bstrTheFields);
SysFreeString(bstrThePopupTitle);
SysFreeString(bstrTheOrderBy);
SysFreeString(bstrTheWhereClause);
SysFreeString(bstrThePosition);
return 0;
}
//Pointer to the safe array that is returned from the VB call //
BSTR HUGEP *pbstr;
wchar_t data[300];
wchar_t *arraylimit = NULL;
// check to see if it is a one-dimensional or two-dimensional array
//
if ( RTNArray->cDims != 1 )
{
//Lock the array //
hr= SafeArrayLock(RTNArray);
long ai[2];
int lower1 = RTNArray->rgsabound[1].lLbound;
int upper1 = RTNArray->rgsabound[1].cElements + lower1;
//Loop through the row first
for(int i = lower1; i < upper1; i++)
{
ai[0]=i;
int lower0 = RTNArray->rgsabound[0].lLbound;
int upper0 = RTNArray->rgsabound[0].cElements + lower0;
//Now loop through each column in the row //
for(int j = lower0; j < upper0; j++)
{
ai[1]=j;
hr=SafeArrayPtrOfIndex(RTNArray, ai, (void HUGEP* FAR*)&pbstr);
if(SUCCEEDED(hr))
{
data[0] = L'\000';
wcscpy(data,pbstr[0]);
char* lpszText2 = _com_util::ConvertBSTRToString(pbstr[0]);
}
}
}
//Unlock the array //
hr= SafeArrayUnlock(RTNArray);
//Destroy the array //
hr = SafeArrayDestroy(RTNArray);
5.C++: converting BSTR to CString or char*
7. OCX converting BSTR* to AnsiString then to WideString and back to BSTR* hell
Users browsing this forum: No registered users and 80 guest