Toon posts:

[C++] BSTR-vraagje

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb in VB:
Visual Basic:
1
2
3
4
5
Private Function Declare Loadpage lib "Dll.dll"( ByRef Stri$ ) as long

Dim p1$
p1 = "/index.php"
Loadpage(p1)


In C++ ziet het er zo uit:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
HRESULT __stdcall Loadpage(BSTR* page1)
{
  // Allerlei dingen
  // ...

  if ( Page1 )
  {
    SysFreeString( *Page1 );
#ifndef UNICODE
    *Page1 = SysAllocStringLen( 0, strlen( Pagina1.Buffer ) );
    size_t size = mbstowcs( 0, Pagina1.Buffer, strlen(Pagina1.Buffer) + 1 );
    mbstowcs( *Page1, Pagina1.Buffer, size );
#else
    *Page1 = SysAllocString( Pagina1.Buffer );
#endif

    delete Pagina1.Buffer;
  }


Deze p1 word juist ontvangen in C++ (als een ANSI string).
De webpagina beschreven in p1 word afgehaald (in een char*) als een ANSI-string.

Dan moet die SysAlloc.. etc code normaal een BSTR van die Pagina1.Buffer maken.

Maar dan word het raar. Als ik in VB even met mijn muis over p1 ga (na uitvoering van deze functie) staat daar tussen elk character een blokje tussen. Zeer waarschijnlijk is dit een UNICODE string geworden. Maar waar is die opeens van ANSI->UNICODE geworden? En hoe kan ik het aanpassen dat die die in VB als een "normale" string ziet (dus zonder die blokjes)?

Verwijderd

Een BSTR is gewoon een unicode string met daarvoor een tellertje hoelang de string is.

voor die hele vage meuk met mbstowcw kan je ook comutil.h includen (en comsupp.lib mee linken en gewoon ) _com_util::ConvertAnsiToBstr (oid ff checken hoe ie precies heet) om je ansi's naar bstr te converteren en visa versa.

Verwijderd

Topicstarter
Mja weet ik, ik heb op CodeProject dat doorgelezen. Waar het gaat over een bug in ConvertStringToBSTR... Dan heb ik de functie die deze persoon voorstelde geimplementeerd. Maar ook dat maakt niets uit. In VB blijf ik die blokjes (dus ik denk UNICODE) krijgen.

Verwijderd

wat doet ie als je gewoon ff simpel test met
code:
1
2
3
4
5
HRESULT __stdcall Loadpage(BSTR* page1)
{
    *Page1 = SysAllocString(L"Testing 123");
    return S_OK;
}

Verwijderd

Topicstarter
Daar krijg ik in P1 (vb een string te staan met: T<blokje>e<blokje>... etc

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Verwijderd schreef op 27 March 2003 @ 01:43:
C++:
1
2
3
4
5
HRESULT __stdcall Loadpage(BSTR* page1)
{
    *Page1 = SysAllocStringLen( 0, strlen( Pagina1.Buffer ) );
    size_t size = mbstowcs( 0, Pagina1.Buffer, strlen(Pagina1.Buffer) + 1 );
    mbstowcs( *Page1, Pagina1.Buffer, size );
Moet dat niet zijn :?
C++:
1
2
3
4
5
HRESULT __stdcall Loadpage(BSTR* page1)
{
    size_t size = mbstowcs( 0, Pagina1.Buffer, strlen(Pagina1.Buffer) + 1 );
    *Page1 = SysAllocStringLen( 0, size );
    mbstowcs( *Page1, Pagina1.Buffer, size );

Niet dat dat iets aan de blokjes doet, maar het is 1) efficienter en 2) correcter

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

en als je er
code:
1
Private Function Declare Loadpage lib "Dll.dll"( ByRef Stri as string )
van maakt?

Verwijderd

Zat nog ff te spitten in msdn en vond dit : [google=Q187912]

Verwijderd

Topicstarter
C++:
1
2
3
4
5
6
7
8
#define String BSTR
#define Function    HRESULT __stdcall

Function LoadPages( String* Page1 = NULL )
{
  *Page1 = SysAllocString(L"Testing 123");
  return S_OK;
}


Visual Basic .NET:
1
2
3
4
5
6
7
8
9
Public Declare Function LoadPages Lib "BattleDLL.dll" (ByRef Page1$) As Long

Private Sub Form_Load()
Dim p1$
  p1 = "/index.php"

  Debug.Assert False 'debug effe!!
  Call LoadPages(p1)
End Sub


Dus zoals je ziet, is het reeds ByRef

en MSAlters, ik gebruik gewoon een functie die de mensen op die url (in mijnvorige post) gebruikten. Maar ik denk wel dat die van jou ietsje rapper zal zijn.

[ Voor 8% gewijzigd door Verwijderd op 27-03-2003 10:21 ]


Verwijderd

Topicstarter
Yarvieh: ik heb mij gebaseerd op dit MSDN article.

Ergens anders in mijn code doe ik het volgende:
Ik krijg een string & een safearray (VB's array dus) door. Ik parse die webpage (die string), die word niet gemodified. Maar in die safearray van udts worden de strings wel gemodified. Maar deze tonen perfect in VB.

Moet ik misschien een UDT maken van 1 BSTR? (even proberen) En als dat zou lukken, waarom lukt dat dan? :S


*edit*
same probleem... Nu krijg ik in deze string ook T<blok>e<blok> etc...

*edit2*
Misschien is dit ook interessant: (is een onderdeel van mijn IDL file)
IDL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
   *****************************
   *                           *
   *  Internet-things          *
   *                           *
   *****************************
*/
    [
      object,
      uuid(B38AFB50-0C00-4755-AFB2-E541C36DDF4C),
      hidden,
      nonextensible,
      oleautomation
    ]
    interface _clsInternet : IUnknown {
      [
        id(40),
        helpstring("Load 2 pages at the same time.")
      ]
      HRESULT LoadPages( [in, out] BSTR* Page1 );
    };

    [
      uuid(B38AFB51-0C00-4755-AFB2-E541C36DDF4C),
      version(1.0)
    ]
    coclass clsInternet {
        [default] interface _clsInternet;
    };

[ Voor 104% gewijzigd door Verwijderd op 27-03-2003 10:43 ]


Verwijderd

Vaagjes, ik zal vanaaf es wat testen. heb hier op de zaak geen c++

Verwijderd

Topicstarter
Mijn dank. En het is inderdaad vaag :S

VB werkt in UNICODE... Ik werk in C++ met ANSI... Ik doe wel de conversie. (mbstocws) Maar toch krijg ik (percies) een 2x geUNICODE-string (dus dat elke char 4 bytes is ipv 2).

Verwijderd

Topicstarter
Op deze site hier staat er de volgende code:

C++:
1
2
3
4
5
6
7
8
BSTR __declspec(dllexport) CALLBACK StringExample(BSTR stringVar)
{
LPSTR buffer;
buffer = (LPSTR)stringVar;
::MessageBox(NULL,buffer,"in C++",0);
buffer = _strrev(buffer);
return(SysAllocString(stringVar));
}


Het probleem hiermee is: er kan maar 1 string doorgegeven worden. (dus maar 1 BSTR in, en ik moet er 2 in hebben, maar ik test voorlopig maar met 1).

En een ander zijdelings vraagje hierbij: "__declspec(dllexport) CALLBACK" wat is dat juist? Ik gebruik altijd "__stdcall".


Voor de rest vind ik eigenlijk niets op google van iemand die hetzelfde probleem heeft gehad.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16:32
Heb je geen mogelijkheid om de string als LPCTSTR ( const char * ) op te vangen en een BSTR terug te geven ?

VB gebruik namelijk intern wel Unicode, maar vertaalt deze voor de buitenwereld automatisch naar een multibyte string.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
mja, het rare is... Ik heb dus in VB een string zoals je ziet.
Die passeer ik ByRef door naar C++
ik ontvang die GOED!! (dus in C++ doe ik "char * invoer = (LPSTR) *Page1;"). invoer = dan de juiste url die ik moet downloaden.

Dan download ik die URL. Die komt te staan in Pagina1.Buffer. Dat is een "char *". Ook dit doet ie perfect.

Maar dan moet ik die Pagina1.Buffer doorsturen naar VB in Page1 (dus in de string waarin ik de url heb doorgegeven vanuit VB).

En daar denk ik dus dat het misloopt. Het enige wat ik niet zie is waar mijn fout ligt.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16:32
Volgens mij is het zo dat VB er van uitgaat dat de externe kant altijd multibyte strings gebruikt.

Maw, van VB - > C++ converteert VB automatisch van UC naar mb en,
C++ -> VB converteert VB automatisch van mb naar UC.

( Kan verklaren waarom jouw string 2x is geconverteerd naar UC )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
VB geeft je dus blijkbaar een LPSTR=char*, geef dan ook een char* terug ipv een bstr_t.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16:32
De gedachte erachter is dat de buitenwereld ( Win32 API ) alleen met mb strings werkt. ( Aangezien niet alle Windows versies UC ondersteunen )

Dwz de 'inkomende' strings zijn altijd mb, ook als ze in de vorm van een BSTR geleverd worden. Hetzelfde geldt voor de 'uitgaande' strings

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1