1

I'm trying to access a .Net library (The Image Resizer) from COM (jscript).

I've tried both IDispatch and class interface generation, as well as [ClassInterface( ClassInterfaceType.AutoDual)] on the class in question.

There is a method with 3 overloads:

Bitmap Build(object, ResizeSettings settings)
void Build(object source, object dest, string settings)
void Build(object source, object dest, ResizeSettings settings)

Calling

Build("file",s); //works

The following both generate "Wrong number of arguments or invalid property assignment" (JScript runtime error)

Build("file","file", s) 
Build("file","file","settings

I can't find any reason that overloads shouldn't work through interop, especially when the arg count differs. Am I missing something?

Update: Here is the full code of the method definitions. The second overload is inacccessible. It's not just these methods - in every overloaded method, I only seem to be able to access the first overload. Is this a undocumented COM bug/design flaw?

    /// <summary>
    /// Provides methods for generating resized images, and for reading and writing them to disk.
    /// Use ImageBuilder.Current to get the current instance (as configured in the application configuration), or use ImageBuilder.Current.Create() to control which extensions are used.
    /// </summary>
    public class ImageBuilder : AbstractImageProcessor, IQuerystringPlugin
    {


        /// <summary>
        /// Resizes and processes the specified source image and returns a bitmap of the result.
        /// This method assumes that transparency will be supported in the final output format, and therefore does not apply a matte color. Use &amp;bgcolor to specify a background color
        /// if you use this method with a non-transparent format such as Jpeg.
        /// </summary>
        /// <param name="source">May be an instance of string (a physical path), VirtualFile, IVirtualBitmapFile, HttpPostedFile, Bitmap, Image, or Stream.</param>
        /// <param name="settings">Resizing and processing command to apply to the.</param>
        public virtual Bitmap Build(object source, ResizeSettings settings) {
            BitmapHolder bh = new BitmapHolder();
            Build(source, bh, settings);
            return bh.bitmap;
        }

        /// <summary>
        /// Resizes and processes the specified source image and stores the encoded result in the specified destination. 
        /// </summary>
        /// <param name="source">May be an instance of string (a physical path or app-relative virtual path), VirtualFile, IVirtualBitmapFile, HttpPostedFile, Bitmap, Image, or Stream. app-relative virtual paths will use the VirtualPathProvider system</param>
        /// <param name="dest">May be a physical path (string), or a Stream instance. Does not have to be seekable.</param>
        /// <param name="settings">Resizing and processing command to apply to the.</param>
        public virtual void Build(object source, object dest, ResizeSettings settings) {
            ResizeSettings s = new ResizeSettings(settings);
Lilith River
  • 16,204
  • 2
  • 44
  • 76
  • I think the code of your COM component (or at least the interface) is more important here... can you post that? – fretje May 17 '11 at 13:53
  • The Component is .NET, the caller is COM. I'll add more code. – Lilith River May 17 '11 at 14:00
  • I don't understand. jscript is not COM. It can easily call COM components though. If you want your .NET component be accessible as a COM component, you have to add code to your .NET component for that (like `ClassInterface(ClassInterfaceType.AutoDual)` what you are talking about in your question). That makes the .NET component a COM server. – fretje May 17 '11 at 14:04
  • 1
    Post the code in which you define a com interface on your .Net component. There may be something wrong with it. Also I remember in the past that I had trouble overloading methods in a COM interface. You may want to try just renaming the method to something else and calling it. – Cole W May 18 '11 at 15:24

2 Answers2

4

True that COM doesn't "do" method overloading.

BUT. see http://msdn.microsoft.com/en-us/library/ms182197(v=vs.80).aspx .

This is a doc page on FxCop, a static analysis tool. But there's a tidbit of information there, which is useful for COM developers:

When overloaded methods are exposed to COM clients, only the first method overload retains its name. Subsequent overloads are uniquely renamed by appending to the name an underscore character '_' and an integer that corresponds to the order of declaration of the overload.

and also see
Overloads in COM interop (CCW) - IDispatch names include suffix (_2, _3, etc)

So, through the COM layer, you could call your original methods with

Build_2("file", "file", s);
Build_3("file", "file", settings);
Community
  • 1
  • 1
Cheeso
  • 189,189
  • 101
  • 473
  • 713
3

Overloading does not work for the interop layer to COM. You could however use optional parameters and hide all other methods from the COM layer:

// COM won't see this.
[ComVisible(false)]
void Test(string a) 

// COM will see this and parameter b is not required
void Test(string a, [DefaultParameterValue(null)] string b)  
Jan-Peter Vos
  • 3,157
  • 1
  • 18
  • 21
  • Neat idea! It's gotta be .NET 2 compatible, though, it's a lib. Maybe I'll have to expose an alternate interface. – Lilith River May 18 '11 at 18:03
  • I am using that same idea in a .NET 2.0 application. Even tough optional parameters are not supported in C# 2.0 the attribute is there and can be applied to parameters. It's just that the C# compiler doesn't do any magic on it. – Jan-Peter Vos May 18 '11 at 18:09