The difference in behaviour of ITypeComp.Bind() is interesting, and I agree
is the main problem here.  However, from what you have said, I'm surprised
that a makepy-backed implementation isn't working for you.  The first thing
we do when getting an object is ask for its type info so we can get the
CLSID of the object.  We then lookup the CLSID in our makepy/gencache map,
and if we find it, the entire process you outline is skipped - we already
know the dispid and flags for each of the attributes.  Thus, given your
objects implement most of the typeinfo stuff correctly, I'm surprised this
isn't working for you.

 

Have you tried running makepy on your typelib?

 

Cheers,

 

Mark

 

From: Obendorf, Keston [mailto:[EMAIL PROTECTED] 
Sent: Thursday, 18 September 2008 10:08 AM
To: [EMAIL PROTECTED]; python-win32@python.org
Subject: RE: [python-win32] COM: Parameterless functions seen as properties

 

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