Thanks.

 

I don't think the issue is that GetTypeInfo() is not returning anything,
but it's returning something that cannot be used properly.

 

I wrote another implementation of the parameterless function, this time
in C++. The implementation in C++ works just fine:

 

retStr = Dispatch("c++implementation").getNLType() 

 

--causes no exceptions and works as intended.

 

I've been stepping through the CDispatch creation process, which on the
account of both C# and C++ implementations seems to go OK. In both
run-throughs, dynamic is able to get both typeinfo and typecomp. I judge
that this happens because in both cases the _olerepr_ of the CDispatch
object is a LazyDispatchItem not DispatchItem, which only happens if
both typeinfo and typecomp are defined. 

 

The implementations diverge, however, in _getattr_, specifically when
calling __LazyMap__. The C++ implementation returns a 1, whereas the C#
implementation returns None. This is due to the fact that in
_LazyAddAttr_ , typecomp.Bind returns (0, None) for all invoke types for
the C# implementation whereas the C++ implementation binds to
INVOKE_FUNC. 

 

(This leads me to conclude that the typecomp for the C# implementation
is bad in some way. That is probably more an issue for a C# mailing
list. I don't think it's Python's fault.)

 

_getattr_ allows recovery from this issue with a last ditch effort,
which you reference in your post as the second thing that could be going
on.  Unfortunately, it sets the invoke type by default to
pythoncom.INVOKE_PROPERTYGET. C# does not seem to care that its function
is not a property, and returns an evaluation of the function rather than
throwing an exception. I don't know if there is a way to prevent this
behavior. 

 

I feel like there's not much information in this posting for all its
words. =(   I figured out HOW it is failing, but not exactly WHY. It
looks like this is a problem in the way C# handles IDispatch and
ITypeInfo.

 

 

P.S. I am new to this whole mailing-list thing, so I don't know exactly
what e-mail addresses to send this post to. Let's hope it winds up in
the right place. 

 

Thanks, Keston

 

________________________________

From: Mark Hammond [mailto:[EMAIL PROTECTED] On Behalf Of Mark
Hammond
Sent: Monday, September 15, 2008 4:06 PM
To: Obendorf, Keston; python-win32@python.org
Subject: RE: [python-win32] COM: Parameterless functions seen as
properties

 

It looks like 2 things are going on:

 

* Your object isn't returning typelib info to Python when it asks.  If
your IDispatch returned something from GetTypeInfo() we could use, this
wouldn't happen.

 

* Without a typelib, Python can't tell if a reference to 'a.foo' is
going to end up being a method call or not (ie, from Python's POV,
a.foo() is just a property fetch for 'foo' and then calling the result.)
When making a property reference, win32com checks for the
ERRORS_BAD_CONTEXT values defined in win32com\client\dynamic.py - if it
sees one of those errors, it assumes it really hit a method and handles
it accordgingly.  But - in your case, your object is succeeding!  The
simplest thing to do here is to have your object refuse to work as a
property using one of the standard error codes, and Python will then try
it as a method.

 

Mark

 

From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On
Behalf Of Obendorf, Keston
Sent: Tuesday, 16 September 2008 8:19 AM
To: python-win32@python.org
Subject: [python-win32] COM: Parameterless functions seen as properties

 

I'm doing COM development in both Python and C#. Things are working
well, but I'm running into an issue where trying to get parameterless
function returns the return value of that function, which Python then
tries to call, causing an error.

 

 

The C# class is an implementation of an IDL-defined interface.

 

//IDL 

interface IService : IDispatch

{

      [id(101)] HRESULT foo([out, retval] BSTR * pstr);

}

 

//C#

[ComImport]

[Guid("/*GUID of IService*/")]

interface IService{}

 

 

[ComVisible(true)]

[ProgId("bar")]

[Guid("Valid GUID")]

public class bar : IService

{

    public bar(){}

 

    public string foo()

    {

        return "foo"; 

    }

}

 

Now, getting a Dispatch of "bar" in Python is where the issue lies.

 

from win32com.client import Dispatch

bar = Dispatch("bar")

str = bar.foo()

 

>>TypeError: 'unicode' object is not callable

 

This is only a problem with the C# class. If the interface is
implemented in Pythong, the above code will work.

 

Now, this issue can be fixed by adding in _FlagAsMethod before calling
bar.foo()

 

bar._FlagAsMethod("foo")

 

I really don't want to have to do that every time I try to call a
parameterless method of a C# COM-object from Python. That's a huge
headache, especially because I am trying to keep the language any one
component is written in a non-issue. 

 

I've started to dive into the source code of dynamic.py and other Client
modules to try and figure out how I can make this distinction at
Dispatch-time, but it's rough going understanding everything that's
going on in there. Does anyone have any pointers or a straight up
solution to this problem? 

 

_______________________________________________
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to