0

I am trying to call a method on a COM Object from a loaded .dll assembly. The problem is very similar to this one, it's just I am working with ironpython 2.7. instead of ironruby.

As with that issue, I can call any property or method which does not take any arguments.

But once a method requires at least one argument, I am getting an error message:

Could not convert argument 0 for call to Open.

Here is the example code:

import clr
import os

shpfilename = "C:/example.shp"
dllsfilename = "C:/mapwindow_dlls"

clr.AddReferenceToFileAndPath(os.path.join(dllsfilename, "Interop.MapWinGIS.dll"))
print "Interop.MapWinGIS.dll loaded: ", "Interop.MapWinGIS" in [assembly.GetName().Name for assembly in clr.References]  # prints: True

import MapWinGIS

sf = MapWinGIS.ShapefileClass()
sf.Open(shpfilename, None)  # raises upper error message

Does anyone know why is this happening? I googled a bit, look like the issue might be with the shpfilename type. So I tried passing the shpfilename by-reference:

shpfilenameRef = clr.Reference[System.String](shpfilename)
sf.Open(shpfilenameRef, None)  # again, raises upper error message

But still the upper error message does not go away.

The Open function has this signature:

Help on method-descriptor Open Open(...)
    Open(self: ShapefileClass, ShapefileName: str, cBack: Callback) -> bool 

// MapWinGIS.ShapefileClass
[DispId(11)]
[MethodImpl(MethodImplOptions.InternalCall)]
public virtual extern bool Open([MarshalAs(UnmanagedType.BStr)] [In] string ShapefileName, [MarshalAs(UnmanagedType.Interface)] [In] ICallback cBack = null);
Community
  • 1
  • 1
marco
  • 899
  • 5
  • 13
  • 21
  • What is the signature of that function? If that is an output parameter, then you might not even need to specify it as it will be included with the return value. If it's declared as an input parameter byref, you probably don't need the reference and could just pass in the value directly (if IronPython does/uses C#'s approach). – Jeff Mercado Jan 26 '16 at 20:56
  • Thank you for the reply@JeffMercado. I do not think "shpfilename" is an output parameter. It may be that I misunderstood you,as I am not really familiar with C#. These might be the signatures of "Open" function: ```Help on method-descriptor Open Open(...) Open(self: ShapefileClass, ShapefileName: str, cBack: Callback) -> bool```. Or: ```// MapWinGIS.ShapefileClass [DispId(11)] [MethodImpl(MethodImplOptions.InternalCall)] public virtual extern bool Open([MarshalAs(UnmanagedType.BStr)] [In] string ShapefileName, [MarshalAs(UnmanagedType.Interface)] [In] ICallback cBack = null);``` – marco Jan 26 '16 at 21:49

1 Answers1

0

So based on the signature, I don't think you need a reference at all, just pass in the name directly. You don't even need to specify the callback, it defaults to None.

I think it should work just like this:

sf.Open(shpfilename)
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
  • Thank you @Jeff Mercado. With ```sf.Open(shpfilename)``` I am getting the same upper error message (Could not convert argument 0 for call to Open.). – marco Jan 26 '16 at 22:46
  • Hmm, it could be that it's complaining about the actual shape file instance, not the parameter like I thought. I'm not sure I could be much more help. it doesn't look like it should fail. Even considering [some C# examples](http://www.mapwindow.org/documentation/mapwingis4.9/getting_started.html#gs6) – Jeff Mercado Jan 26 '16 at 22:51
  • For some reason the ```MapWinGIS.Shapefile``` class does not contain the "Open" function, even though in C# examples they use it. This is why I used the ```MapWinGIS.ShapefileClass``` class which does contain the "Open" function. But nevertheless, when I try to use ```MapWinGIS.Shapefile``` class: ```sf = MapWinGIS.Shapefile()```, an error appears: "Cannot create instances of Shapefile because it is abstract" – marco Jan 26 '16 at 22:55
  • 1
    I don't know what sorts of things the runtime does to make COM objects usable, but what I do know is that there's typically in interface and some object that implements it. C# hides away some of this so you can instantiate the interface directly. Other languages I suspect needs to instantiate the implementing class. I guess `ShapefileClass` is the implementing class. – Jeff Mercado Jan 26 '16 at 23:00
  • Forgive me for my ignorance. But if I understood you correctly, the ```ShapefileClass``` class might be ironpython's alternative to C# ```Shapefile``` class? – marco Jan 26 '16 at 23:05
  • 1
    Yes, that's what I'm thinking. In C# intellisense, you'll probably see `Shapefile` displayed as in interface and no actual `ShapefileClass` class. – Jeff Mercado Jan 26 '16 at 23:23