|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Late Binding Return Value Weirdnesswith late binding that surprises me. VB and VBS are not my normal milieux, so I'm hoping someone can point me to a document that describes this. Here's the setup. We have a COM server, written in Python. For completeness, here is the script: ----- testserver.py ----- import pythoncom class TestSrv(object): _reg_clsid_ = '{C7B89AAC-99B7-48A1-8088-D77A867CBB0C}' _reg_desc_ = 'TestSrv COM+ Server' _reg_progid_ = 'TestSrv.Application' _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER _public_methods_ = ['SetValue', 'GetValue'] def __init__(self): self.ABC = '' def SetValue(self, what, newval): if what == 'ABC': self.ABC = newval def GetValue(self, what): if what == 'ABC': return self.ABC if __name__=='__main__': import win32com.server.register win32com.server.register.UseCommandLine(TestSrv, debug=0) ----- end ----- This server has two methods. Even without knowing Python, you can see that neither method alters its parameters. They touch internal state only. We call this from a VB module: ----- Module1.vb ----- Module Module1 Sub Main() Dim testSrvObj As Object Dim what As String, value As String, retvalue As String testSrvObj = CreateObject("TestSrv.Application") value = "ABCValue" what = "ABC" Console.WriteLine("What " & what) Console.WriteLine("Value " & value) testSrvObj.SetValue(what, value) Console.WriteLine("What " & what) Console.WriteLine("Value " & value) testSrvObj.SetValue("ABC", value) Console.WriteLine("What " & what) Console.WriteLine("Value " & value) retvalue = testSrvObj.GetValue("ABC") Console.WriteLine("What " & what) Console.WriteLine("Value " & value) Console.ReadKey() End Sub End Module ----- end ----- The following VBScript exhibits the exact same behavior: ----- testClient.vbs ----- Dim testSrvObj, what, value, retvalue Set testSrvObj = CreateObject("TestSrv.Application") value = "ABCValue" what = "ABC" WScript.Echo "What", what WScript.Echo "Value", value testSrvObj.SetValue what, value WScript.Echo "What", what WScript.Echo "Value", value testSrvObj.SetValue "ABC", value WScript.Echo "What", what WScript.Echo "Value", value retvalue = testSrvObj.GetValue("ABC") WScript.Echo "What", what WScript.Echo "Value", value WScript.Echo "Return", retvalue ----- end ----- The surprise here is that, after the first call to SetValue, the value of "what" is changed. After the second call to SetValue, the value of "value" is changed. After some experimentation, we discover that these variables are getting set to whatever SetValue returns. In the example I posted, we return the Python "None" value, which translates to VB's Nothing. If I change the server to return a string, the VB variables receive that string. This question was originally posted to a Python mailing list with the VBScript client. I assumed this was a bug in the Python COM handling, which is why I tried it in VB2005. However, I dumped the IL from the VB code above, and discovered to my great surprise that the IL has code to do this! In the first case, it takes the return value, casts it to string, and stores it in "what". In the second case, it stuffs the return value into "value". I can't duplicate this in C++ or C#, because they do not have automatic support for late binding. The method calls return a value, and it's up to me to handle it. Python does have support for late binding, but calling this from a Python client does not exhibit this behavior. I have searched through two dozen documents on late binding in VB, and I have found nothing to describe this. It turns out to be easy to work around; if I turn the method call into a function call, it works: retvalue = testSrvObj.SetValue( what, value ) Or, if I turn the parameters into ByVal parameters, it works: testSrvObj.SetValue (what), (value) However, I am stunned that I should have to do that. The semantics boggle me. Any clues greatly appreciated. -- Tim Roberts, t***@probo.com, DDK MVP Providenza & Boekelheide, Inc. Hello Tim,
> I've been doing COM a long time, but I've just come across a behavior I'm not very familiar with late binding but I also am a bit surprised by > with late binding that surprises me. VB and VBS are not my normal > milieux, so I'm hoping someone can point me to a document that > describes this. this behavior. Let's try and get python out of the picture here. Can you post the IDL file for the Python server? -- Jared Parsons [MSFT] jared***@online.microsoft.com All opinions are my own. All content is provided "AS IS" with no warranties, and confers no rights. Hello Tim,
> Also check out this article.>> I've been doing COM a long time, but I've just come across a behavior >> with late binding that surprises me. VB and VBS are not my normal >> milieux, so I'm hoping someone can point me to a document that >> describes this. >> > I'm not very familiar with late binding but I also am a bit surprised > by this behavior. Let's try and get python out of the picture here. > Can you post the IDL file for the Python server? http://blogs.msdn.com/cambecc/archive/2004/06/01/145309.aspx -- Jared Parsons [MSFT] jared***@online.microsoft.com All opinions are my own. All content is provided "AS IS" with no warranties, and confers no rights. Jared Parsons [MSFT] <jared***@online.microsoft.com> wrote:
> There is no IDL. What you saw in my post is all that there is. The Python>Hello Tim, > >> I've been doing COM a long time, but I've just come across a behavior >> with late binding that surprises me. VB and VBS are not my normal >> milieux, so I'm hoping someone can point me to a document that >> describes this. > >I'm not very familiar with late binding but I also am a bit surprised by >this behavior. Let's try and get python out of the picture here. Can you >post the IDL file for the Python server? COM services use reflection to synthesize IDispatch handlers for the class. That's why we have to use late binding. By the way, I keep saying "we", but in fact this code belongs to someone on one of the Python mailing lists. The question intrigued me, because I thought I was a pretty studly COM guy, and now I MUST find the answer. The Cameron Beccario posting was useful; I'm going to try to concoct a C# test case using Microsoft.VisualBasic.CompilerServices.LateCall and see if I can duplicate it there. In the end, however, I suspect the answer is "because that's how it works". -- - Tim Roberts, t***@probo.com Providenza & Boekelheide, Inc. Tim,
I would set first Option Strict On in top of your program, than you can edit the most obvious late binding errors which are not needed. If you can than not resolve one or two, than you can set it again off. At this moment there are in my opinion more changes on late binding errors than are needed. Be aware that you use very much VBScript code in VBNet which can give errors. What is something the same as using C in C#. By instance instancing an non global Object in VBNet is \\\ Dim myOjbect as New TheClass /// Cor Show quoteHide quote "Tim Roberts" <t***@probo.com> schreef in bericht news:cmv7a292j684vdgmomqc2qlmaugjju0eru@4ax.com... > I've been doing COM a long time, but I've just come across a behavior > with late binding that surprises me. VB and VBS are not my normal > milieux, so I'm hoping someone can point me to a document that > describes this. > > Here's the setup. We have a COM server, written in Python. For > completeness, here is the script: > > ----- testserver.py ----- > import pythoncom > > class TestSrv(object): > > _reg_clsid_ = '{C7B89AAC-99B7-48A1-8088-D77A867CBB0C}' > _reg_desc_ = 'TestSrv COM+ Server' > _reg_progid_ = 'TestSrv.Application' > _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER > _public_methods_ = ['SetValue', 'GetValue'] > > def __init__(self): > self.ABC = '' > > def SetValue(self, what, newval): > if what == 'ABC': > self.ABC = newval > > def GetValue(self, what): > if what == 'ABC': > return self.ABC > > if __name__=='__main__': > import win32com.server.register > win32com.server.register.UseCommandLine(TestSrv, debug=0) > ----- end ----- > > This server has two methods. Even without knowing Python, you can see > that neither method alters its parameters. They touch internal state > only. > > We call this from a VB module: > > ----- Module1.vb ----- > Module Module1 > Sub Main() > Dim testSrvObj As Object > Dim what As String, value As String, retvalue As String > testSrvObj = CreateObject("TestSrv.Application") > > value = "ABCValue" > what = "ABC" > > Console.WriteLine("What " & what) > Console.WriteLine("Value " & value) > testSrvObj.SetValue(what, value) > Console.WriteLine("What " & what) > Console.WriteLine("Value " & value) > testSrvObj.SetValue("ABC", value) > Console.WriteLine("What " & what) > Console.WriteLine("Value " & value) > retvalue = testSrvObj.GetValue("ABC") > Console.WriteLine("What " & what) > Console.WriteLine("Value " & value) > Console.ReadKey() > End Sub > > End Module > ----- end ----- > > The following VBScript exhibits the exact same behavior: > > ----- testClient.vbs ----- > Dim testSrvObj, what, value, retvalue > Set testSrvObj = CreateObject("TestSrv.Application") > > value = "ABCValue" > what = "ABC" > > WScript.Echo "What", what > WScript.Echo "Value", value > testSrvObj.SetValue what, value > WScript.Echo "What", what > WScript.Echo "Value", value > testSrvObj.SetValue "ABC", value > WScript.Echo "What", what > WScript.Echo "Value", value > retvalue = testSrvObj.GetValue("ABC") > WScript.Echo "What", what > WScript.Echo "Value", value > WScript.Echo "Return", retvalue > ----- end ----- > > The surprise here is that, after the first call to SetValue, the value > of "what" is changed. After the second call to SetValue, the value of > "value" is changed. After some experimentation, we discover that > these variables are getting set to whatever SetValue returns. In the > example I posted, we return the Python "None" value, which translates > to VB's Nothing. If I change the server to return a string, the VB > variables receive that string. > > This question was originally posted to a Python mailing list with the > VBScript client. I assumed this was a bug in the Python COM handling, > which is why I tried it in VB2005. However, I dumped the IL from the > VB code above, and discovered to my great surprise that the IL has > code to do this! In the first case, it takes the return value, casts > it to string, and stores it in "what". In the second case, it stuffs > the return value into "value". > > I can't duplicate this in C++ or C#, because they do not have > automatic support for late binding. The method calls return a value, > and it's up to me to handle it. Python does have support for late > binding, but calling this from a Python client does not exhibit this > behavior. > > I have searched through two dozen documents on late binding in VB, and > I have found nothing to describe this. It turns out to be easy to > work around; if I turn the method call into a function call, it works: > > retvalue = testSrvObj.SetValue( what, value ) > > Or, if I turn the parameters into ByVal parameters, it works: > > testSrvObj.SetValue (what), (value) > > However, I am stunned that I should have to do that. The semantics > boggle me. > > Any clues greatly appreciated. > -- > Tim Roberts, t***@probo.com, DDK MVP > Providenza & Boekelheide, Inc. "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> wrote: "Late binding errors"? I'm not sure I understand. Late binding is not> >I would set first Option Strict On in top of your program, than you can edit >the most obvious late binding errors which are not needed. If you can than >not resolve one or two, than you can set it again off. allowed under Option Strict On, and this problem is entirely related to late binding. >At this moment there are in my opinion more changes on late binding errors Again, I'm not sure what you are saying. To use a Python COM server, we>than are needed. have to use late binding. >Be aware that you use very much VBScript code in VBNet which can give I don't think you read my post closely enough. I had a VB example, and a>errors. What is something the same as using C in C#. separate VBScript example. Both happen to exhibit the same behavior. -- - Tim Roberts, t***@probo.com Providenza & Boekelheide, Inc. Tim,
Thanks for the lesson, Cor Show quoteHide quote "Tim Roberts" <t***@probo.com> schreef in bericht news:1ebea2t3da4aegcq6durv2h57oljnt8u29@4ax.com... > "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> wrote: >> >>I would set first Option Strict On in top of your program, than you can >>edit >>the most obvious late binding errors which are not needed. If you can than >>not resolve one or two, than you can set it again off. > > "Late binding errors"? I'm not sure I understand. Late binding is not > allowed under Option Strict On, and this problem is entirely related to > late binding. > >>At this moment there are in my opinion more changes on late binding errors >>than are needed. > > Again, I'm not sure what you are saying. To use a Python COM server, we > have to use late binding. > >>Be aware that you use very much VBScript code in VBNet which can give >>errors. What is something the same as using C in C#. > > I don't think you read my post closely enough. I had a VB example, and a > separate VBScript example. Both happen to exhibit the same behavior. > -- > - Tim Roberts, t***@probo.com > Providenza & Boekelheide, Inc.
ActiveX.exe and RaiseEvent
need help with a string manipulation. + and & operators Threads do not Terminate! Hindi numbers in Graphics class OpenFileDialog Handle Leak read textbox into array - vb2005 DataGridView Question - VB.NET 2005 REGULAR EXPRESSION extract a word and text around it change cursor to hourglass (WaitCursor) between try..catch |
|||||||||||||||||||||||