PDA - personal digital assistant

Visualizza versione completa : HOWTO: Convert a C string 100% compatible to Visual Basic



Admin
09/11/2004, 18:23
This sample shows how to convert a C string to a 100% compatible Visual Basic string.


STDMETHODIMP CClass::get_ErrorMessage(int dwErrorCode, BSTR *pVal)
{
char *sz = (char *)alloca(1024);
BSTR tmp = NULL;
int n;
switch(dwErrorCode)
{
case 0:
strcpy(sz, "OK.");
break;
default:
strcpy(sz, "Unknown error!");
}

n = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, NULL, 0);
tmp = (BSTR)alloca(n);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, tmp, n);

*pVal = SysAllocString(tmp);

return S_OK;
}


Variant for standard DLL's:


BSTR ErrorMessage(int dwErrorCode)
{
char *sz = (char *)alloca(1024);
BSTR tmp = NULL;
int n;
switch(dwErrorCode)
{
case 0:
strcpy(sz, "OK.");
break;
default:
strcpy(sz, "Unknown error!");
}

n = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, NULL, 0);
tmp = (BSTR)alloca(n);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, tmp, n);

return SysAllocString(tmp);

}

Admin
05/01/2005, 11:15
/////////////////////////////////////////////////////////////////////////////
// C String to BSTR conversion (1)
inline BSTR __C2B(char *szString)
{
BSTR res = NULL;
BSTR bs;
DWORD n;
char *sz = NULL;
if(*szString && szString)
{
sz = strdup(szString);
n = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, NULL, 0);
if(n)
{
res = (BSTR)malloc(n);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, res, n);
}
}
bs = SysAllocString(res);

free(sz);
return bs;
}
/////////////////////////////////////////////////////////////////////////////
// C String to BSTR conversion (2)
inline BSTR __C2B(char *szString, int dwSize)
{
BSTR res = NULL;
BSTR bs;
DWORD n = (DWORD)dwSize;
char *sz = NULL;
if(*szString)
{
sz = (char *)malloc(dwSize);
memcpy(sz, szString, dwSize);
n = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, n, NULL, 0);
if(n)
{
res = (BSTR)malloc(n);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, res, n);
}
}
bs = SysAllocStringLen(res, n);

free(sz);
return bs;
}
/////////////////////////////////////////////////////////////////////////////
// BSTR to C String conversion
inline char *__B2C(BSTR bString)
{
int i;
int n = (int)SysStringLen(bString);
char *sz;
sz = (char *)malloc(n + 1);

for(i = 0; i < n; i++)
{
sz = (char)bString[i];
}
sz[i] = 0;
return sz;
}



Important note:


Enable Runtime Exceptions must be switched to ON, or else you may get difficult to trace errors while debugging. Switching this option to ON does not increase your code size if you don't make use of the try-catch-construct.

Admin
13/01/2005, 16:16
This code does not require Error Trapping, but does not run with wide character sets:


/////////////////////////////////////////////////////////////////////////////
// C String to BSTR conversion (1)
inline BSTR __C2B(char *szString)
{
BSTR bs;
BSTR res = NULL;
int i;
int n;
if(szString)
{
n = lstrlen(szString) + 1;
res = (BSTR)malloc(n << 1);
if(res)
{
for(i = 0; i < n; i++)
{
res[i] = (USHORT)(UCHAR)szString[i];
}
}
}

bs = SysAllocString(res);

free(res);

return bs;
}

/////////////////////////////////////////////////////////////////////////////
// C String to BSTR conversion (2)
inline BSTR __C2B(char *szString, int dwExactSize)
{
BSTR bs;
BSTR res = NULL;
int i;

if(szString)
{
res = (BSTR)malloc(dwExactSize << 1);
if(res)
{
for(i = 0; i < dwExactSize; i++)
{
res[i] = (USHORT)(UCHAR)szString[i];
}
}
}

bs = SysAllocStringLen(res, dwExactSize);

free(res);

return bs;
}

/////////////////////////////////////////////////////////////////////////////
// BSTR to C String conversion
inline char *__B2C(BSTR bString)
{
int i;
int n = (int)SysStringLen(bString);
char *sz;

sz = (char *)malloc(n + 1);

for(i = 0; i < n; i++)
{
sz[i] = (char)bString[i];
}
sz[i] = 0;

return sz;
}