Solved

c++ BSTR to ATL object

Posted on 2001-06-13
13
505 Views
Last Modified: 2013-11-25
I'm trying to send BSTRs to an ATL component from C++.
The BSTR's appear to be created ok from the client, but when watching the incoming BSTRS in the component the debugger reports 'Invalid string format'.

method set up as follows...

in idl file...

[id(3), helpstring("method VerifyUser")] HRESULT VerifyUser([in] BSTR UserID, [in] BSTR Password, [out] VARIANT_BOOL *bCorrect);

in cpp file...

STDMETHODIMP CHMAccounts::VerifyUser(BSTR UserID, BSTR Password, VARIANT_BOOL *bCorrect)

and called from the client...

  BSTR x = SysAllocString(wUser); // wchar_t
  BSTR y = SysAllocString(wPass);
  hr = pHMAI->VerifyUser(x, y, &ok);
  SysFreeString(x);
  SysFreeString(y);


Can someone tell me what I'm doing wrong please.


0
Comment
Question by:mark50
  • 5
  • 5
  • 2
  • +1
13 Comments
 
LVL 2

Expert Comment

by:missionImpossible
ID: 6185483
have you set debugger/environment to show unicode-strings?
In MSVC it is in menu options->Debug->show Unicode-strings?
0
 
LVL 2

Expert Comment

by:MadYugoslav
ID: 6185528
Try to use CString class to convert char and wchar:

CString xx(wUser);
CString yy(wPass);
BSTR x = xx.SysAllocString();
BSTR y = yy.SysAllocString();
0
 
LVL 2

Expert Comment

by:missionImpossible
ID: 6185536
why he should use mfc for this?
0
 
LVL 2

Expert Comment

by:MadYugoslav
ID: 6185555
This is only one solution.
0
 
LVL 3

Expert Comment

by:elcapitan
ID: 6185572
Another way to see unicode strings:
In the watch window, add ',su' after the variable name. For example, when you dubug your component, write in the watch window: UserID,su in order to see the unicode string in UserID.

--EC--
0
 

Author Comment

by:mark50
ID: 6185592
Setting the 'show unicode strings' shows that the bstr is passed ok.

the program aborts when trying to execute an SQL statement.
strange thing is that the component works from VB...

the full method code is.........

STDMETHODIMP CHMAccounts::VerifyUser(BSTR UserID, BSTR Password, VARIANT_BOOL *bCorrect)
{
  FieldPtr  fp;
  _variant_t   Value, Pword(Password);
  _bstr_t cmdText;
 

  *bCorrect = -1;
 
  if(!bconnected)
    return E_FAIL;
 
  // Create command object
  if(!SUCCEEDED(m_command.CreateInstance(__uuidof(Command))))
    return E_FAIL;    
 
  // Set command parameters.
  m_command->ActiveConnection = m_connection;
  cmdText = L"Select Password from Accounts where UserID = '";
  cmdText += UserID;
  cmdText += L"'";
 
  if(!SUCCEEDED(m_command->put_CommandText( cmdText )))
    return E_FAIL;
 
  if(!SUCCEEDED(m_command->put_CommandType( adCmdText )))
    return E_FAIL;
 
  // create recordset object
  if(!SUCCEEDED(m_recordset.CreateInstance(__uuidof(Recordset))))
    return E_FAIL;
 
  // Execute ******* CAUSES EXCEPTION *******
  m_recordset = m_command->Execute( NULL, NULL, 0 );
  if(m_recordset->adoEOF)
  {
    *bCorrect = false;
    return S_OK;
  }
 
  m_recordset->MoveFirst();
  //Get the value
  fp = m_recordset->Fields->GetItem("Password");
  Value = fp->Value;

  if(Value != Pword)
    *bCorrect = false;
 
  return S_OK;
}

can you see why ?
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 2

Expert Comment

by:missionImpossible
ID: 6185629
isn't this another question? however, how do you defined the passed VARIANT_BOOL, the 'ok'-variable?

hr = pHMAI->VerifyUser(x, y, &ok);

The error must be in the definition of this var, in VB this seems to be correct.
0
 

Author Comment

by:mark50
ID: 6185708
I suppose it is a different question though the cause of the original problem is the same.

VARIANT_BOOL ok = false;

It doesn't matter how the ok variable is defined because this has nothing to do with the sql statement being executed.

the value of cmdtext is a valid SQL statement....

{"Select Password from Accounts where UserID = 'User1'" (1)}

this is taken straight from the watch window.


0
 
LVL 2

Expert Comment

by:missionImpossible
ID: 6185758
have you debugged where it aborts? believe me, the problem is at the client.

can you look into the idl-file. is the last parameter in your method an [out] or an [in, out] parameter?

0
 

Author Comment

by:mark50
ID: 6185872
I suppose it is a different question though the cause of the original problem is the same.

VARIANT_BOOL ok = false;

It doesn't matter how the ok variable is defined because this has nothing to do with the sql statement being executed.

the value of cmdtext is a valid SQL statement....

{"Select Password from Accounts where UserID = 'User1'" (1)}

this is taken straight from the watch window.


0
 

Author Comment

by:mark50
ID: 6185877
[id(3), helpstring("method VerifyUser")] HRESULT VerifyUser([in] BSTR UserID, [in] BSTR Password, [out] VARIANT_BOOL *bCorrect);
0
 
LVL 2

Accepted Solution

by:
missionImpossible earned 30 total points
ID: 6185945
sorry, but I was too blind to see your comment at the execute-statement.

the execute returns an _RecordsetPtr. How did you declared your recordset-member m_recordset?

here's a code snipped how I call the execute:

_RecordsetPtr m_spRecordset;

VARIANT varAffected;
varAffected.vt = VT_I2;
m_spRecordset = m_spCommand->Execute(&varAffected,NULL,0);

and second thing: Is your connection-Object in open state?
0
 

Author Comment

by:mark50
ID: 6186004
My connection object is not in an open state.

Consequently I feel like a complete tit !

here's your points.

thanks
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now