smegghead
asked on
Bug in .net - surely not !!!!
There may be something I'm doing wrong here... but it seems too odd to be true.
I have authored a VC++.net ATL component
One of the methods in one of the classes of this component has a parameter of 'BSTR* InString'
When browsing this component within object browser (from VB), it says 'ByRef InString as string'
I call the function (from VB)
I modify the value of InString
I return from the function
----
The string is the same as it was when I first passed it in
Now, this is the strange part...
If I write the following code...
---------------
dim x as new MyLibFile.MyClass
dim y as string
y="hello"
x.ChangeValue(y) ' the function changes the value to 'goodbye'
msgbox y
--------------- The result is "hello"
whereas... if I do the following...
---------------
dim x as object = new MyLibFile.MyClass
dim y as string
y="hello"
x.ChangeValue(y) ' the function changes the value to 'goodbye'
msgbox y
--------------- The result is "goodbye"
How can this be ???
I've tried to re-create this using a very simple one-class, one-method ATL component, and a very simple VB program to call it... and it still has the same behaviour. It also works as expected when I late bind using 'set x=createobject("MyLibFile. MyClass")'
I have authored a VC++.net ATL component
One of the methods in one of the classes of this component has a parameter of 'BSTR* InString'
When browsing this component within object browser (from VB), it says 'ByRef InString as string'
I call the function (from VB)
I modify the value of InString
I return from the function
----
The string is the same as it was when I first passed it in
Now, this is the strange part...
If I write the following code...
---------------
dim x as new MyLibFile.MyClass
dim y as string
y="hello"
x.ChangeValue(y) ' the function changes the value to 'goodbye'
msgbox y
--------------- The result is "hello"
whereas... if I do the following...
---------------
dim x as object = new MyLibFile.MyClass
dim y as string
y="hello"
x.ChangeValue(y) ' the function changes the value to 'goodbye'
msgbox y
--------------- The result is "goodbye"
How can this be ???
I've tried to re-create this using a very simple one-class, one-method ATL component, and a very simple VB program to call it... and it still has the same behaviour. It also works as expected when I late bind using 'set x=createobject("MyLibFile.
Try to free the BSTR from c++ before you assign it
ASKER
The original BSTR or the newly assigned one ??
The only difference i can see is:
dim x as new MyLibFile.MyClass
Now, if you do this:
dim x as MyLibFile.MyClass = new MyLibFile.MyClass
I guess you still get the wrong behaviour...
Now, I am not sure about .net syntax, but can you try this:
x.ChangeValue y
CHeers
dim x as new MyLibFile.MyClass
Now, if you do this:
dim x as MyLibFile.MyClass = new MyLibFile.MyClass
I guess you still get the wrong behaviour...
Now, I am not sure about .net syntax, but can you try this:
x.ChangeValue y
CHeers
ASKER
Hi Angeliii
Yeah, I still get the wrong behaviour using your suggested method.
.net automatically puts brackets around everything.. so it will allways read
x.ChangeValue(y)
I can see where you were coming from though, as you used to be able to imply 'byval' by surrounding the parameter with brackets.
i.e.
z=x.ChangeValue((y))
Would always pass 'y' as byval... not sure if this is still the case with .net.
PS. I've tried freeing both BSTRs b4 returning to the calling app - still no joy.
Yeah, I still get the wrong behaviour using your suggested method.
.net automatically puts brackets around everything.. so it will allways read
x.ChangeValue(y)
I can see where you were coming from though, as you used to be able to imply 'byval' by surrounding the parameter with brackets.
i.e.
z=x.ChangeValue((y))
Would always pass 'y' as byval... not sure if this is still the case with .net.
PS. I've tried freeing both BSTRs b4 returning to the calling app - still no joy.
In c++, try this
if (*InString != nULL )
::SysFreeString(m_str);
if (*InString != nULL )
::SysFreeString(m_str);
In c++, try this
if (*InString != nULL )
::SysFreeString(m_str);
if (*InString != nULL )
::SysFreeString(m_str);
My mistake
In c++, try this
if (*InString != NULL )
::SysFreeString(*InString) ;
In c++, try this
if (*InString != NULL )
::SysFreeString(*InString)
ASKER
This is my code...
STDMETHODIMP CGenFunc::get_FirstPiece(B STR* MainString, BSTR Delimiter, BSTR* pVal)
{
AFX_MANAGE_STATE(AfxGetSta ticModuleS tate());
int FindPos;
CString Delim=Delimiter;
CString MainCS=*MainString;
CString Result;
FindPos=MainCS.Find(Delim) ;
if (FindPos==-1)
{
Result=MainCS.Left(0); // returns a blank string
*pVal=MainCS.AllocSysStrin g();
}
else
{
Result=MainCS.Mid(FindPos+ Delim.GetL ength());
*pVal=MainCS.Left(FindPos) .AllocSysS tring();
}
SysFreeString(*MainString) ;
*MainString=Result.AllocSy sString();
return S_OK;
}
STDMETHODIMP CGenFunc::get_FirstPiece(B
{
AFX_MANAGE_STATE(AfxGetSta
int FindPos;
CString Delim=Delimiter;
CString MainCS=*MainString;
CString Result;
FindPos=MainCS.Find(Delim)
if (FindPos==-1)
{
Result=MainCS.Left(0); // returns a blank string
*pVal=MainCS.AllocSysStrin
}
else
{
Result=MainCS.Mid(FindPos+
*pVal=MainCS.Left(FindPos)
}
SysFreeString(*MainString)
*MainString=Result.AllocSy
return S_OK;
}
If you cannot find delim
if (FindPos==-1)
{
Result=MainCS.Left(0); // returns a blank string
*pVal=MainCS.AllocSysStrin g(); // return the same string here
}
should it be
if (FindPos==-1)
{
Result=MainCS.Left(0); // returns a blank string
*pVal=Result.AllocSysStrin g();
}
if (FindPos==-1)
{
Result=MainCS.Left(0); // returns a blank string
*pVal=MainCS.AllocSysStrin
}
should it be
if (FindPos==-1)
{
Result=MainCS.Left(0); // returns a blank string
*pVal=Result.AllocSysStrin
}
ASKER
Nope, there is no problem with the logic, it works perfectly.
The function returns the first piece of the string and chops that first piece out of the InString.
If there are no delimiters in the string, it is obvisouly the last piece, so it returns the string and blanks the InString.
I have a problem with the value being passed back...
it works perfectly if I use late binding, but otherwise it doesn't..
The function returns the first piece of the string and chops that first piece out of the InString.
If there are no delimiters in the string, it is obvisouly the last piece, so it returns the string and blanks the InString.
I have a problem with the value being passed back...
it works perfectly if I use late binding, but otherwise it doesn't..
I create test program on version 2000 (release version) has no poblem. What version are you running
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
The only difference I can see there is that I'm using a CString and you're using a CComBSTR... I'll try that and give it a go.
ASKER
I've moved away from c++ / VB and I'm concentrating on c#
although I'm still intrigued as to why this is happening.
I would like to keep this open for a bit longer, to give me time to go back and readdress this issue... but it's really whether EE will allow the question to be left open.
although I'm still intrigued as to why this is happening.
I would like to keep this open for a bit longer, to give me time to go back and readdress this issue... but it's really whether EE will allow the question to be left open.
ASKER
Thanks for your help on this question.
As I said above, I never did resolve this, but it became less of an issue as I moved away from c++/VB.
Thanks anyway.
As I said above, I never did resolve this, but it became less of an issue as I moved away from c++/VB.
Thanks anyway.