By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,501 Members | 1,678 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,501 IT Pros & Developers. It's quick & easy.

Late Binding Return Value Weirdness

P: n/a
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, ti**@probo.com, DDK MVP
Providenza & Boekelheide, Inc.
Jun 29 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
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?
--
Jared Parsons [MSFT]
ja******@online.microsoft.com
All opinions are my own. All content is provided "AS IS" with no warranties,
and confers no rights.
Jun 29 '06 #2

P: n/a
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?


Also check out this article.

http://blogs.msdn.com/cambecc/archiv...01/145309.aspx

--
Jared Parsons [MSFT]
ja******@online.microsoft.com
All opinions are my own. All content is provided "AS IS" with no warranties,
and confers no rights.
Jun 29 '06 #3

P: n/a
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
"Tim Roberts" <ti**@probo.com> schreef in bericht
news:cm********************************@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, ti**@probo.com, DDK MVP
Providenza & Boekelheide, Inc.

Jun 30 '06 #4

P: n/a
Jared Parsons [MSFT] <ja******@online.microsoft.comwrote:
>
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?
There is no IDL. What you saw in my post is all that there is. The Python
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, ti**@probo.com
Providenza & Boekelheide, Inc.
Jul 2 '06 #5

P: n/a
"Cor Ligthert [MVP]" <no************@planet.nlwrote:
>
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, ti**@probo.com
Providenza & Boekelheide, Inc.
Jul 2 '06 #6

P: n/a
Tim,

Thanks for the lesson,

Cor

"Tim Roberts" <ti**@probo.comschreef in bericht
news:1e********************************@4ax.com...
"Cor Ligthert [MVP]" <no************@planet.nlwrote:
>>
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, ti**@probo.com
Providenza & Boekelheide, Inc.

Jul 2 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.