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")'
LVL 10
smeggheadAsked:
Who is Participating?
 
EDDYKTCommented:
By the way, this is my test code


in c++

STDMETHODIMP Ctt::retstring(BSTR * instring)
{
     //if (*instring != NULL )
     //     ::SysFreeString(*instring);

     CComBSTR tt="goodbye";
     *instring = tt.Detach();
     return S_OK;
}


in vb

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim x As New testproj.Ctt()
        Dim y As String
        y = "hello"
        x.retstring(y) ' the function changes the value to 'goodbye'
        MsgBox(y)

    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim x As Object = New testproj.Ctt()
        Dim y As String
        y = "hello"
        x.retstring(y) ' the function changes the value to 'goodbye'
        MsgBox(y)

    End Sub
0
 
EDDYKTCommented:
Try to free the BSTR from c++ before you assign it
0
 
smeggheadAuthor Commented:
The original BSTR or the newly assigned one ??
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
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
0
 
smeggheadAuthor Commented:
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.
0
 
EDDYKTCommented:
In c++, try this


if (*InString != nULL )
::SysFreeString(m_str);
0
 
EDDYKTCommented:
In c++, try this


if (*InString != nULL )
::SysFreeString(m_str);
0
 
EDDYKTCommented:
My mistake


In c++, try this


if (*InString != NULL )
    ::SysFreeString(*InString);
0
 
smeggheadAuthor Commented:
This is my code...

STDMETHODIMP CGenFunc::get_FirstPiece(BSTR* MainString, BSTR Delimiter, BSTR* pVal)
{
     AFX_MANAGE_STATE(AfxGetStaticModuleState());

     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.AllocSysString();
     }
     else
     {
          Result=MainCS.Mid(FindPos+Delim.GetLength());
          *pVal=MainCS.Left(FindPos).AllocSysString();
     }
     SysFreeString(*MainString);
     *MainString=Result.AllocSysString();
     return S_OK;
}
0
 
EDDYKTCommented:
If you cannot find delim


 if (FindPos==-1)
    {
         Result=MainCS.Left(0); // returns a blank string
         *pVal=MainCS.AllocSysString();  // return the same string here
    }


should it be


if (FindPos==-1)
    {
         Result=MainCS.Left(0); // returns a blank string
         *pVal=Result.AllocSysString();
    }
0
 
smeggheadAuthor Commented:
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..
0
 
EDDYKTCommented:
I create test program on version 2000 (release version) has no poblem. What version are you running
0
 
smeggheadAuthor Commented:
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.
0
 
smeggheadAuthor Commented:
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.
0
 
smeggheadAuthor Commented:
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.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.