_bstr_t ??
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 23

Thread: _bstr_t ??

  1. #1
    Join Date
    Apr 2004
    Posts
    204

    _bstr_t ??

    I am trying to execute this line: OpenDatabase

    I have tried the following three methods (none work):
    Code:
    _bstr_t strMdbPath = "C:\\test.mdb";
    dbs = wsp->OpenDatabase (strMdbPath);
    Code:
    dbs = wsp->OpenDatabase ( _bstr_t("C:\\test.mdb") );
    Code:
    dbs = wsp->OpenDatabase ( "C:\\test.mdb" );
    Is there something more I should understand about _bstr_t
    Last edited by mmscg; April 21st, 2005 at 07:58 PM.

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    11,197

    Re: _bstr_t ??

    What doesn't work about them?

    Arjay

  3. #3
    Join Date
    Apr 2004
    Posts
    204

    Re: _bstr_t ??

    If I execute any of the OpenDatabase lines in the above post,
    my program crashes.

    If I execute this line, the program does not crash
    Code:
    wsp = pDBE->CreateWorkspace ("mySpace","admin","");

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    11,197

    Re: _bstr_t ??

    Are you checking to make sure wsp isn't NULL? What error are you seeing?

    Arjay

  5. #5
    Join Date
    Apr 2004
    Posts
    204

    Re: _bstr_t ??

    The error was:
    Runtime Error!
    abnormal program termination
    As it turns out, it was a silly error (they usually are for me anyway ),
    I had imported DAO350.DLL (used with Access97 I guess), and I was trying
    to open an Access2000 database which seems to require DAO360.DLL

    Anyways, that part is fixed.

  6. #6
    Join Date
    Apr 2004
    Posts
    204

    Re: _bstr_t ??

    I have numeric data retreival working with this code:
    Code:
    char buff[256];
    int code;
    code = int( ptrFields->Item[ "ID" ]->Value );
    wsprintf(buff,"ID: %d",code);
    MessageBox(hWndMain,buff,"Message",MB_OK);
    but how do I do something similar with text data
    something along the lines of:
    Code:
    char buff[256];
    char code;
    MYstr = _bstr_t( ptrFields->Item[ "Employee" ]->Value );
    wsprintf(buff,"Employee name: %char",MYstr);
    MessageBox(hWndMain,buff,"Message",MB_OK);

  7. #7
    Join Date
    Apr 2004
    Posts
    204

    Re: _bstr_t ??

    I created a simple database and simply want (using win32 C++ only)
    to connect and display
    Code:
    Employee  ID
    John       2
    Bill       4
    Jack       6
    Tom        8
    I basically have done this; no errors and everything (for the most part) works.

    To display IDs:
    Code:
    while (!rs->EndOfFile)
    {
        int code;
        code = ( ptrFields->Item[ "ID" ]->Value );
        wsprintf(buff,"ID: %d",code);
        MessageBox(hWndMain,buff,"Message",MB_OK);
    }
    
    Produces output:
    ID: 2
    ID: 4
    ID: 6
    ID: 8
    Doing this to display Employees
    Code:
    while (!rs->EndOfFile)
    {
        _bstr_t MYstr;
        MYstr = ( ptrFields->Item[ "Employee" ]->Value );
        wsprintf(buff,"Employee: %d",MYstr);
        MessageBox(hWndMain,buff,"Message",MB_OK);
    }
    
    Produces output:
    Employee: 12398232
    Employee: 12398232
    Employee: 12398232
    Employee: 12398232
    Not sure what the number 12398232 is (an address?) but at least no errors!


    My attempt to convert to a string is this
    Code:
    while (!rs->EndOfFile)
    {
        char str[50]; 
        str = ( ptrFields->Item[ "Employee" ]->Value );
        wsprintf(buff,"Employee: %d",str);
        MessageBox(hWndMain,buff,"Message",MB_OK);
    }
    
    I get this error:
    
    cannot convert from '_variant_t' to 'char[50]'
    What is the proper way to work with strings in C++?

  8. #8
    Join Date
    Apr 2004
    Posts
    204

    Re: _bstr_t ??

    I think if someone can show me how to use char*, I can figure this out.

    I am having problems with the last line in the following:
    Code:
    _variant_t MyVariant;
    
    MyVariant = ptrFields->Item[ "Employee" ]->Value;  // get VARIANT and put into _variant_t
    
    ???? = (char*)_bstr_t(MyVariant);                  // put into _bstr_t and cast to char*
    I don't understand what it means to "cast to char*"
    Last edited by mmscg; April 26th, 2005 at 09:56 PM.

  9. #9
    Arjay's Avatar
    Arjay is offline Moderator / MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    11,197

    Re: _bstr_t ??

    Quote Originally Posted by mmscg
    I think if someone can show me how to use [/b]char*[/b], I can figure this out.

    I am having problems with the last line in the following:
    Code:
    _variant_t MyVariant;
     
    MyVariant = ptrFields->Item[ "Employee" ]->Value; // get VARIANT and put into _variant_t
    ???? = (char*)_bstr_t(MyVariant); // put into _bstr_t and cast to char*
    I don't understand what it means to cast to char*
    Okay you need a bit of background. First of all the variant can store a variety of items including a BSTR. It can also store integers, arrays and other data types. A BSTR is a UNICODE (two byte or wchar_t) string. The string length is a integer stored in the memory location preceding the data in the string.

    Both the _variant_t and _bstr_t objects are classes that wrap the native VARIANT and BSTR data types. These classes provide some overloaded operators that help make conversions easier.

    Okay now on to converting your stuff (this assumes that the value of "Employee" is a bstr contained within the variant):

    Code:
    // Retrieve the employee variant 
    _variant_t vEmployee( ptrFields->Item[ "Employee" ]->Value );
     
    // Convert into a string
    _bstr_t bstrEmployee( vEmployee );
     
    // Extraction operator converts the bstr into a LPCTSTR
    // NOTE: LPCTSTR are compiler setting dependent (either char* or wchar_t*)
    // based on whether you are compiling in ANSI or UNICODE
    MessageBox( hWndMain, bstrEmployee, "Employee", MB_OK );
    Arjay

  10. #10
    Join Date
    Apr 2004
    Posts
    204

    Re: _bstr_t ??

    THAT WORKS!!!!

    Thank you Arjay!!

    (now I have to step back and try and understand it)

  11. #11
    Join Date
    Apr 2004
    Posts
    204

    Re: _bstr_t ??

    Why is this not sinking in for me?

    Arjay's code works great... I just want to properly understand it.

    Arjay's code:
    Code:
    _variant_t vEmployee ( ptrFields->Item[ "Employee" ]->Value );  // Retrieve variant
    _bstr_t bstrEmployee( vEmployee );                              // Convert into a string
    MessageBox( hWndMain, bstrEmployee, "Employee", MB_OK );        // Display
    Slightly modified (this also works);
    Code:
    _variant_t vEmployee;                                     // Declare _variant_t variable
    vEmployee = ( ptrFields->Item[ "Employee" ]->Value );	  // Retrieve the employee variant
    
    _bstr_t bstrEmployee( vEmployee );           	          // Convert into a string
      
    MessageBox( hWndMain, bstrEmployee, "Employee", MB_OK );  // Display
    What should bstrEmployee be set equal to in the following if I declare it separately like so?
    Code:
    _variant_t vEmployee;                                     // Declare _variant_t variable
    vEmployee = ( ptrFields->Item[ "Employee" ]->Value );	  // Retrieve the employee variant
    
    _bstr_t bstrEmployee;                                     // Declare _bstr_t variable
    bstrEmployee = ( vEmployee );                             // Convert into a string ???????
    
    MessageBox( hWndMain, bstrEmployee, "Employee", MB_OK );  // Display

  12. #12
    Arjay's Avatar
    Arjay is offline Moderator / MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    11,197

    Re: _bstr_t ??

    Quote Originally Posted by mmscg
    What should bstrEmployee be set equal to in the following if I declare it separately like so?
    Code:
    _variant_t vEmployee; // Declare _variant_t variable
    vEmployee = ( ptrFields->Item[ "Employee" ]->Value );	 // Retrieve the employee variant
     
    _bstr_t bstrEmployee; // Declare _bstr_t variable
    bstrEmployee = ( vEmployee ); // Convert into a string ???????
     
    MessageBox( hWndMain, bstrEmployee, "Employee", MB_OK ); // Display
    As I mentioned earlier, the _bstr_t and _variant_t classes provide conversions for you. The way my example was coded performed the conversions in the constructors which was convenient but unfortunately hid much of what was going on. To get a better idea of how this works, take a look in msdn for the different types of _bstr_t constructors - you'll notice that one of them is a _variant_t, so that's why the line
    Code:
     _bstr_t bstrEmployee( vEmployee );
    works.

    The following uses an assignment operator.
    Code:
     _bstr_t bstrEmployee; 
    bstrEmployee = (vEmployee );
    Unfortunately, there isn't any assignment operator for _bstr_t that takes a variant. So if you know the _variant_t holds a bstr, you can just access the bstr member of the variant structure directly or perform a cast which uses an extraction operator.

    Access the bstr member of the variant
    Code:
     _bstr_t bstrEmployee; 
    bstrEmployee = ( vEmployee.bstrVal );
    Access the bstr member via an extraction operator
    Code:
     _bstr_t bstrEmployee; 
    bstrEmployee = ( (_bstr_t)vEmployee );
    Arjay

  13. #13
    Join Date
    Apr 2004
    Posts
    204

    Re: _bstr_t ??

    Your explanation is very clear... I now can see what is happening.

    Thank you once again.

    A further problem; I am now trying to concatenate the strings and it is not working for me
    (I don't know if the problem is a bstr issue or a string.h issue).

    This is what I have (I have "commented out" the lines that cause errors):
    Code:
    // Get value from ID field
    	_variant_t vID;		
    	vID = ( recordset->Fields->GetItem(L"ID")->GetValue() );	
    	
            _bstr_t bstrID;
    	bstrID = ( (_bstr_t)vID );
    				
    	MessageBox( hWndMain, bstrID, "ID", MB_OK );  
    
    	string myString1;
    	myString1=bstrID;
    	//MessageBox( hWndMain, myString1, "ID", MB_OK );            // Doesn't work
    
    // Get value from Employee field
    	_variant_t vEmployee;	
    	vEmployee = ( recordset->Fields->GetItem(L"Employee")->GetValue() );
    
    	_bstr_t bstrEmployee;                                     
    	bstrEmployee = ( (_bstr_t)vEmployee );	
    	   
    	MessageBox( hWndMain, bstrEmployee, "Employee", MB_OK );  
    
    	string myString2;
    	myString2=bstrEmployee;
    	//MessageBox( hWndMain, myString2, "Employee", MB_OK );      // Doesn't work
    
    // Combine the values
    	string myString3;
    	//myString3 = "ID: " + myString1 + " - Name: " + myString2;  // Doesn't work
    	//MessageBox( hWndMain, myString3, "DB Record", MB_OK );     // Doesn't work
    I am especially confused as to why this line fails:

    myString3 = "ID: " + myString1 + " - Name: " + myString2;

    (as I have checked and re-checked and cannot see anything wrong with it)
    Last edited by mmscg; May 2nd, 2005 at 07:48 PM.

  14. #14
    Arjay's Avatar
    Arjay is offline Moderator / MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    11,197

    Re: _bstr_t ??

    std::string (and the unicode std::wstring) are another type of string object, so let's look at the failures one by one.

    The first one doesn't work because you need to call the c_str() method in order to convert the std::string object into a null terminated c-styled string.
    Code:
    	string myString2;
    	myString2=bstrEmployee;
    	//MessageBox( hWndMain, myString2, "Employee", MB_OK );
    	MessageBox( hWndMain, myString2.c_str(), "Employee", MB_OK );
    The next one doesn't work because you can't add multiple strings (or string objects) at the same time. You probably got the following error:
    C2678: binary '+' : no operator found which takes a left-hand operand of type 'const char [10]' (or there is no acceptable conversion)

    You have a couple of options:

    Code:
    	string myString3;
    	//myString3 = "ID: " + myString1 + " - Name: " + myString2;
     
    	// Option 1 - Use the append() method
    	myString3.append( "ID: " );
    	myString3.append( myString1 );
    	myString3.append( " - Name: " );
    	myString3.append( myString2 );
     
    	// Option 2 - Perform each concatination on a separate line
    	myString3 = "ID: ";
    	myString3 += myString1;
    	myString3 += " - Name: ";
    	myString3 += myString2;
     
    	MessageBox( hWndMain, myString3.c_str(), "DB Record", MB_OK );
    Arjay

  15. #15
    Join Date
    Apr 2004
    Posts
    204

    Re: _bstr_t ??

    Again, when it is explained to me it seems quite simple.

    The problem I seem to be having with C++ is that there seems to be so many ways to do the same thing,
    but only one that is correct for a given situation.

    Anyways, your solutions to both my problems work and I can continue with my project... Thank You!

    p.s.
    Given that I am only using the MessageBox as a temporary tool for debugging as I code this project,
    and will eventually probably use a ListBox or ComboBox (when I figure out how to use these) in which to display these strings,
    do you think I selected the right string library (string.h) for what I am doing?
    or should I be using something different for the string manipulation?

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center