mihe has asked for the wisdom of the Perl Monks concerning the following question:

I’m trying to pass a COM object from C# code to Perl.

At the moment I’m wrapping my Perl code with PerlNET (PDK 9.4; ActiveState) and I have defined a simple subroutine (+ required pod declaration) in Perl to pass objects from C# to the wrapped Perl module.

It seems that the objects I pass are not recognized correctly as COM objects.

An example:

In C# (.NET 4.0), the ScriptControl is used to load a simple class from a file written in VBScript.

var host = new ScriptControl(); host.Language = "VBScript"; var text = File.ReadAllText("TestScript.vbs"); host.AddCode(text); dynamic obj = host.Run("GetTestClass");

What I get (obj) is of type System.__ComObject. When I pass it to my Perl/PerlNET assembly and try to call method Xyz() in Perl I get the following (runtime) exception:

Can't locate public method Xyz() for System.__ComObject

If, however, I do more or less the same thing in Perl, it works. (In the following case, passing only the contents of my .vbs file as parameter.). I can even use the script control:

sub UseScriptControl { my ($self, $text) = @_; my $script = Win32::OLE->new('ScriptControl'); $script->{Language} = 'VBScript'; $script->AddCode($text); my $obj = $script->Run('GetTestClass'); $obj->Xyz(); }

Now, calling $obj->Xyz() works fine (using Win32::OLE).

In both cases I use

use strict; use Win32; use Win32::OLE::Variant;

Another approach:

I can invoke methods by using InvokeMember of class System.Type if I specify *exactly* which overload I want to use and which types I’m passing:

use PerlNET qw(typeof); typeof($obj)->InvokeMember("Xyz", PerlNET::enum("System.Reflection.BindingFlags.InvokeMethod"), PerlNET::null("System.Reflection.Binder"), $obj, "System.Object[]"->new());

Using this approach would mean rewriting the whole wrapped Perl module. And using this syntax..

Now I am wondering if I am losing both the advantages of the dynamic keyword in .NET 4.0 and the dynamic characteristics of Perl (with Win32::OLE) by using PerlNET with COM objects.

It seems like my preferred solution boils down to some way of mimicking the behaviour of the dynamic keyword in C#/.NET 4.0.

Or finding some way of converting the passed COM object to something that will be recognized as compatible with Win32::OLE. Maybe extract some information of the __ComObject for it to be identified correctly as COM object.

I have to add that I posted to the PDK discussion site too (but didn’t get any response yet): http://community.activestate.com/node/18247

I would greatly appreciate any help - or advise on where to look further.