Aangezien het COM is, begin met het definiëren van een interface. Laten we het simpel houden.
[Guid("a5ee0756-0cbb-4cf1-9a9c-509407d5eed6")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IGreet
{
[DispId(1)]
string Hello(string name);
[DispId(2)]
Object onHello { get; set; }
}
Vervolgens de implementatie:
[ProgId("Cheeso.Greet")]
[ComVisible(true)]
[Guid("bebcfaff-d2f4-4447-ac9f-91bf63b770d8")]
[ClassInterface(ClassInterfaceType.None)]
public partial class Greet : IGreet
{
public Object onHello { get; set; }
public String Hello(string name)
{
var r = FireEvent();
return "Why, Hello, " + name + "!!!" + r;
}
}
De belangrijkste truc is de methode FireEvent
. Dit werkte voor mij.
private string FireEvent()
{
if (onHello == null) return " (N/A)";
onHello
.GetType()
.InvokeMember
("",
BindingFlags.InvokeMethod,
null,
onHello,
new object [] {});
return "ok";
}
Compileer dat allemaal samen, registreer het met regasm:
%NET64%\regasm.exe Cheeso.Greet.dll /register /codebase
... En gebruik het dan als volgt uit JScript:
var greet = new ActiveXObject("Cheeso.Greet"), response;
greet.onHello = function() {
WScript.Echo("onHello (Javascript) invoked.");
};
response = greet.Hello("Fred");
WScript.Echo("response: " + response);
Het werkt.
Je kunt het ook vanuit VBScript noemen:
Sub onHello ()
WScript.Echo("onHello (VBScript) invoked.")
End Sub
Dim greet
Set greet = WScript.CreateObject("Cheeso.Greet")
greet.onHello = GetRef("onHello")
Dim response
response = greet.Hello("Louise")
WScript.Echo("response: " & response)
Om parameters met deze benadering van C# naar JScript door te geven, denk ik dat objecten IDispatch moeten zijn, maar natuurlijk kun je eenvoudige waarden terugsturen die als string, int enzovoort worden gemarcheerd en die worden gemargreerd zoals je zou verwachten.
Pas bijvoorbeeld de C# -code aan om een referentie naar zichzelf en het nummer 42 terug te sturen.
onHello
.GetType()
.InvokeMember
("",
BindingFlags.InvokeMethod,
null,
onHello,
new object [] { this, 42 });
Dan kun je dat in jscript krijgen zoals:
greet.onHello = function(arg, num) {
WScript.Echo("onHello (Javascript) invoked.");
WScript.Echo(" num = " + num + " stat=" + arg.status);
};
Of in VBScript als volgt:
Sub onHello (obj, num)
WScript.Echo("onHello (VBScript) invoked. status=" & obj.status )
WScript.Echo(" num= " & num)
End Sub
NB: U kunt uw jscript-gebeurtenisafhandelingsfunctie definiëren om minder args te accepteren dan worden verzonden door het C# -object wanneer u de "event" aanroept. In mijn ervaring moet je de gebeurtenishandler in VBScript ontwerpen om expliciet het juiste aantal argumenten te accepteren.