LPSTR to BSTR
-
Hallo
Ich schreibe gerade ein kleines Plugin für ein Program. Im Rahmen dies Plugins will ich auf Excel datein zurückgreifen.
Dabei such ich mir mit GetOpenFileName(...) den Pfad zu der Excel Datei und würde sie gerne mit folgenden Code öffnen :
IDispatch *pXlBook; { VARIANT result; VariantInit(&result); VARIANT x; x.vt = VT_BSTR; // x.bstrVal = SysAllocString(L"C:\\..."); x.bstrVal = SysAllocString((LPCWSTR) ofn.lpstrFile); AutoWrap(DISPATCH_METHOD, &result, pXlBooks, L"Open", 1, x); pXlBook = result.pdispVal; SysFreeString(x.bstrVal); }
dabei entsteht dann in der laufzeit folgender Error :
IDispatch::Invoke("Open"=00000783) faild w/err 0x800a03ec
ich glaube das der fehler bei der convertierung for LPSTR zu BSTR entsteht.
mit bestem dank
Richard
-
LPSTR, BSTR, GetOpenFileName und IDispatch sind in Standard-C++ unbekannt - die Fehlermeldng und vieles aus deinem Code auch.
Wohin willt du verschoben werden, C++/CLI oder WinAPI? (Ich kanns nicht erkennen...)
-
pumuckl schrieb:
LPSTR, BSTR, GetOpenFileName und IDispatch sind in Standard-C++ unbekannt - die Fehlermeldng und vieles aus deinem Code auch.
Wohin willt du verschoben werden, C++/CLI oder WinAPI? (Ich kanns nicht erkennen...)Am besten nach MFC (Visual C++) verschieben. Es handelt sich um COM (mit C++) und hat nichts mit C++/CLI zu tun.
-
theta schrieb:
Am besten nach MFC (Visual C++) verschieben. Es handelt sich um COM (mit C++) und hat nichts mit C++/CLI zu tun.
Mit MFC auch nicht. WinAPI passt schon.
Zum Problem: Der Cast auf LPCWSTR macht hier vermutlich aus einer Compilerfehlermeldung einen Fehler zur Laufzeit.
-
Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Man kann Zeiger nicht einfach casten! Warum machst Du überhaupt bei SysAllolcString einen cast?
Ist das ein Unicode oder MBCS Projekt?Am einfachsten sind die ATL Markos. Also hier T2BSTR...
-
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.