Solved

Bug in .net - surely not !!!!

Posted on 2002-05-15
15
202 Views
Last Modified: 2013-11-25
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")'
0
Comment
Question by:smegghead
  • 7
  • 7
15 Comments
 
LVL 26

Expert Comment

by:EDDYKT
Comment Utility
Try to free the BSTR from c++ before you assign it
0
 
LVL 10

Author Comment

by:smegghead
Comment Utility
The original BSTR or the newly assigned one ??
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
Comment Utility
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
 
LVL 10

Author Comment

by:smegghead
Comment Utility
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
 
LVL 26

Expert Comment

by:EDDYKT
Comment Utility
In c++, try this


if (*InString != nULL )
::SysFreeString(m_str);
0
 
LVL 26

Expert Comment

by:EDDYKT
Comment Utility
In c++, try this


if (*InString != nULL )
::SysFreeString(m_str);
0
 
LVL 26

Expert Comment

by:EDDYKT
Comment Utility
My mistake


In c++, try this


if (*InString != NULL )
    ::SysFreeString(*InString);
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 10

Author Comment

by:smegghead
Comment Utility
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
 
LVL 26

Expert Comment

by:EDDYKT
Comment Utility
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
 
LVL 10

Author Comment

by:smegghead
Comment Utility
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
 
LVL 26

Expert Comment

by:EDDYKT
Comment Utility
I create test program on version 2000 (release version) has no poblem. What version are you running
0
 
LVL 26

Accepted Solution

by:
EDDYKT earned 50 total points
Comment Utility
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
 
LVL 10

Author Comment

by:smegghead
Comment Utility
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
 
LVL 10

Author Comment

by:smegghead
Comment Utility
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
 
LVL 10

Author Comment

by:smegghead
Comment Utility
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

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

772 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

10 Experts available now in Live!

Get 1:1 Help Now