Are you checking to make sure wsp isn't NULL? What error are you seeing?
Arjay
mmscg
April 22nd, 2005, 07:50 PM
The error was:
Runtime Error!
abnormal program termination
As it turns out, it was a silly error (they usually are for me anyway :D ),
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.
mmscg
April 23rd, 2005, 01:45 AM
I have numeric data retreival working with this code:
Produces output:
Employee: 12398232
Employee: 12398232
Employee: 12398232
Employee: 12398232
Not sure what the number 12398232 is (an address?) but at least no errors!
What is the proper way to work with strings in C++?
mmscg
April 26th, 2005, 10:52 PM
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:
_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*"
Arjay
April 26th, 2005, 11:17 PM
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:
_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):
// 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
mmscg
April 26th, 2005, 11:46 PM
THAT WORKS!!!! :D
Thank you Arjay!!
(now I have to step back and try and understand it)
mmscg
May 1st, 2005, 11:32 PM
Why is this not sinking in for me?
Arjay's code works great... I just want to properly understand it.
_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
_bstr_t bstrEmployee( vEmployee );works.
The following uses an assignment operator.
_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
_bstr_t bstrEmployee;
bstrEmployee = ( vEmployee.bstrVal );
Access the bstr member via an extraction operator
_bstr_t bstrEmployee;
bstrEmployee = ( (_bstr_t)vEmployee );
Arjay
mmscg
May 2nd, 2005, 08:27 PM
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):
// Get value from ID field
_variant_t vID;
vID = ( recordset->Fields->GetItem(L"ID")->GetValue() );
(as I have checked and re-checked and cannot see anything wrong with it)
Arjay
May 2nd, 2005, 10:26 PM
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.
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)
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?
Arjay
May 2nd, 2005, 11:26 PM
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.
Yeah, it can be confusing. The problem really isn't so much C++, it's that you are covering many areas of technologies (not that that's a problem really :thumb: ). For strings, here's a short list:
_bstr_t // Com type strings
CComBSTR // ATL's COM type strings
std::string // standard library string class
CString // MFC or ATL string class
Each have their own quarks, but you pretty much have them covered (except for CString)
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?If you are using MFC, you can use the CString class which is easier for non-bstr string manipulation than std::string. If you are using VC7 or higher, you can also use it in non-MFC projects by including atlstr.h.
mmscg
May 2nd, 2005, 11:45 PM
I don't use MFC at all, so I will use std::string // standard library string class then.
I am using VB.NET 2003 (is this VC7?) so if I understand you correctly I should also learn to use CString,
because I can use it also in my non-MFC projects.
Arjay
May 2nd, 2005, 11:59 PM
It's kind of confusing, but in .net 2003 CString is actually CStringT which is used in MFC and ATL. ATL typically is used for building COM applications, but you can use its string functionality by including the atlstr.h header.
Btw, for std::string you should include <string> instead of <string.h>.
Arjay
mmscg
May 3rd, 2005, 08:18 PM
I stumbled upon this:
static_cast<const char*>
and incorporated into my code.
(in doing so I was able to get rid of the <string> library include)
It works, and I was wondering if this solution is acceptable?
Here is how I used it in my code:
while(!recordset->ADOEOF)
{
// Get value from ID field
_variant_t vID;
vID = ( recordset->Fields->GetItem(L"ID")->GetValue() );
_bstr_t bstrID;
bstrID = ( (_bstr_t)vID );
// Get value from Employee field
variant_t vEmployee;
vEmployee = ( recordset->Fields->GetItem(L"Employee")->GetValue() );
_bstr_t bstrEmployee;
bstrEmployee = ( (_bstr_t)vEmployee );
It reads pretty clear, but I have to admit I have no idea what static_cast<const char*> does.
Arjay
May 4th, 2005, 12:29 PM
I stumbled upon this:
static_cast<const char*>
and incorporated into my code.
(in doing so I was able to get rid of the <string> library include)
It works, and I was wondering if this solution is acceptable?
Here is how I used it in my code:
while(!recordset->ADOEOF)
{
// Get value from ID field
_variant_t vID;
vID = ( recordset->Fields->GetItem(L"ID")->GetValue() );
_bstr_t bstrID;
bstrID = ( (_bstr_t)vID );
// Get value from Employee field
variant_t vEmployee;
vEmployee = ( recordset->Fields->GetItem(L"Employee")->GetValue() );
_bstr_t bstrEmployee;
bstrEmployee = ( (_bstr_t)vEmployee );
It reads pretty clear, but I have to admit I have no idea what static_cast<const char*> does.It's using one of the extraction operators I mentioned earlier. See operator wchar_t* | char* (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang__bstr_t.asp) in msdn. You don't really need to use the static_cast, because the compiler can figure it out for you. See my earlier post.
MessageBox( hWndMain, bstrEmployee, "Employee", MB_OK ); // No cast
Arjay
mmscg
May 4th, 2005, 05:08 PM
I have a knack for making things more difficult than need be :D ...
Thanks!
srrad
January 22nd, 2010, 12:57 AM
Can you explain what is this _bstr_t ? I am beginner in this vc++.But I got a code to analyse.I am not getting the code....Can any one help me by explainig this doubts?
hoxsiew
January 22nd, 2010, 08:34 AM
First, a BSTR is a string allocated by OLE that can be passed between COM/DCOM processes and typically requires a call to SysAllocString() to create, then it is passed to the COM process, then must be freed by SysFreeString().
The _bstr_t class is a RAII class that does the grunt work for you. It allocates COM resources in the constructor and releases them in the destructor when the object goes out of scope. It also has members and operator overloads that do all the conversions from various string types used by windows. This makes it easier on the programmer as they don't have to worry about all the COM intricacies.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.