LPSTR to BSTR
-
BSTR BSTRFromStrA(LPCSTR str) { BSTR bstr; int nLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, NULL, 0) - 1; if(NULL != (bstr = SysAllocStringLen(NULL, nLen))) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, nLen, bstr, nLen); return(bstr); } #ifdef UNICODE #define BSTRFromStr SysAllocString #else #define BSTRFromStr BSTRFromStrA #endif
Damit sollte das gehen:
IDispatch *pXlBook; { VARIANT result; VariantInit(&result); VARIANT x; x.vt = VT_BSTR; // x.bstrVal = SysAllocString(L"C:\\..."); x.bstrVal = BSTRFromStr(ofn.lpstrFile); AutoWrap(DISPATCH_METHOD, &result, pXlBooks, L"Open", 1, x); pXlBook = result.pdispVal; SysFreeString(x.bstrVal); }
-
@Mox: Nein! So geht es garantiert nicht!
Was BSTRFromStrA zurückgibt ist eben kein BSTR!
-
Martin Richter schrieb:
@Mox: Nein! So geht es garantiert nicht!
Was BSTRFromStrA zurückgibt ist eben kein BSTR!Sondern was?
-
Ich habe gerade mal nach dem von Dir genannten Macro gesucht. Siehe da, es wird auch hier kein BSTR zurückgegeben. Aus atlconv.h:
_Check_return_ _Ret_opt_z_ inline BSTR A2WBSTR( _In_opt_z_ LPCSTR lp, _In_ int nLen = -1) { if (lp == NULL || nLen == 0) return NULL; USES_CONVERSION_EX; BSTR str = NULL; ATLPREFAST_SUPPRESS(6385) int nConvertedLen = MultiByteToWideChar(_acp_ex, 0, lp, nLen, NULL, 0); ATLPREFAST_UNSUPPRESS() int nAllocLen = nConvertedLen; if (nLen == -1) nAllocLen -= 1; // Don't allocate terminating '\0' str = ::SysAllocStringLen(NULL, nAllocLen); if (str != NULL) { int nResult; nResult = MultiByteToWideChar(_acp_ex, 0, lp, nLen, str, nConvertedLen); ATLASSERT(nResult == nConvertedLen); if(nResult != nConvertedLen) { SysFreeString(str); return NULL; } } return str; } _Ret_opt_z_ inline BSTR T2BSTR(_In_opt_z_ LPCTSTR lp) { return A2WBSTR(lp); }
T2BSTR funktioniert also garantiert auch nicht. Was schlägst Du vor?
-
Mox schrieb:
Ich habe gerade mal nach dem von Dir genannten Macro gesucht. Siehe da, es wird auch hier kein BSTR zurückgegeben.
Hmmm, das mußt Du uns schon genauer erläutern
Ich lese aus Deinem Code folgendes:
BSTR str = NULL; ... return str;
Hier wird also ganz klar BSTR zurückgegeben!
Martin
-
Mmacher schrieb:
Mox schrieb:
Ich habe gerade mal nach dem von Dir genannten Macro gesucht. Siehe da, es wird auch hier kein BSTR zurückgegeben.
Hmmm, das mußt Du uns schon genauer erläutern
Ich? Wieso ich? Der andere Martin hat diese Behauptung aufgestellt! Zitat: "Nein! So geht es garantiert nicht!"
Bei mir funktioniert das allerdings seit Jahren einwandfrei.
Mmacher schrieb:
Ich lese aus Deinem Code folgendes:
BSTR str = NULL; ... return str;
Hier wird also ganz klar BSTR zurückgegeben!
Das sehe ich auch so, aber eher wegen:
bstr = SysAllocStringLen(...);
-
Du irrst! Ein BSTR ist eben nicht nur ein wchar_t* sondern ein Zeiger der durch SysAlloc... Funktionen allokiert wird. Dazu wird übrigends vor dem eigentlichen String auch noch die Länge des Buffers abgelegt.
BSTR haben eine komplett eigene Speicherverwaltung...Aus einem Zeiger wird durch casten kein BSTR!
Lies die MSDN wenn Du mir nicht glaubst...
-
Martin Richter schrieb:
Du irrst! Ein BSTR ist eben nicht nur ein wchar_t* sondern ein Zeiger der durch SysAlloc... Funktionen allokiert wird.
Genau dieses SysAlloc... benutze ich doch, Du Scherzbold!
Dazu wird übrigends vor dem eigentlichen String auch noch die Länge des Buffers abgelegt.
Das weiss ich. Das macht die SysAlloc...-Funktion, die ich verwende, automatisch!
BSTR haben eine komplett eigene Speicherverwaltung...
Das ist mir bekannt!
Aus einem Zeiger wird durch casten kein BSTR!
Das ist mit klar, deswegen mache ich das auch nicht!
Lies die MSDN wenn Du mir nicht glaubst...
Das habe ich getan!
-
Übrigens: Da ich nicht weiss was Du so rauchst, würde ich gerne mal die Stelle gezeigt bekommen, an der Du in meiner BSTRFromStrA-Funktion den cast siehst. Ich selber kann das ohne Anleitung leider nicht sehen.
-
Sorry! Du hast recht! Ich habe den SysAllocStringLen übersehen.
Tut mir leid. Die funktion ist vollkommen OK...Entschuldige nochmals.