-
Notifications
You must be signed in to change notification settings - Fork 150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ClearScript execution of VBS code does not support ByRef parameter passing #511
Comments
Hello @Rison-Hub, When a script invokes managed code, ClearScript uses the C# compiler to select the correct method – or construct a suitable generic method – based on the call signature. Unlike Visual Basic and VBScript, C# forces the caller to specify the passing mechanism for each argument. Because script languages usually give you no way to do that, ClearScript provides its own solution. To pass something by reference to a managed method, you must use a host variable. Here's an example based on your code above: using (var engine = new VBScriptEngine()) {
engine.AddHostObject("zp", new VBClass());
engine.AddHostObject("host", new HostFunctions());
engine.Execute(@"
Option Explicit
Sub Main
dim reftest
reftest = host.newVar(clng(0))
zp.testRef 5, reftest.ref
zp.print reftest
End Sub
Main
");
} Good luck! |
Executing the code snippet you provided will result in an exception: "The most suitable overload method for 'VBLibrary.VBClass.testRef(int, ref object)' has some invalid arguments." |
Oops, sorry. We had modified using (var engine = new VBScriptEngine()) {
engine.AddHostObject("zp", new VBClass());
engine.AddHostObject("host", new HostFunctions());
engine.AddHostType(typeof(object));
engine.Execute(@"
Option Explicit
Sub Main
dim reftest
reftest = host.newVar(object, clng(0))
zp.testRef 5, reftest.ref
zp.print reftest
End Sub
Main
");
} |
Thank you for your suggestion, but there is another question. My second parameter in the VB.NET method is an optional parameter. If I want to pass only one argument, how can I achieve a ByRef parameter that is not specified and request the method?
C# code
Error message: Microsoft.ClearScript.ScriptEngineException: "The method 'testRef' does not have an overload that takes '1' parameter." |
Hi again,
Yes, unfortunately, C# doesn't support optional by-reference parameters, and, as we discussed above, ClearScript uses C#'s invocation semantics. One workaround is to add an overload without the optional parameter: Public Sub testRef(ByVal OutStr As Integer)
testRef(OutStr, 0)
End Sub
Public Sub testRef(ByVal OutStr As Integer, Optional ByRef iShow As Integer = 0)
iShow = iShow + OutStr
Console.WriteLine("testRef: " & iShow & "!")
End Sub Cheers! |
|
Please reopen this issue if you have additional questions about this topic. Thank you! |
@ClearScriptLib I have encountered another issue. I want to pass a two-dimensional array and process it in VB.NET. How can I call and output the processed result values in VBS? VBS code
VB.NET Code
C# Code
Executing zp.print ByReftest(0,0) throws an error: Microsoft.ClearScript.ScriptEngineException: "The object does not support the requested invocation operation." |
Hi @Rison-Hub,
Hmm. In the meantime, in this particular case, there's no need to use a host variable at all. Here's a working sample: Public Sub Print(strInfo As Object)
Console.WriteLine("strInfo : " & strInfo & "!")
End Sub
Public Sub testArr(Ipar As Integer, arr As Object)
arr(0, 0) = arr(0, 0) + Ipar
Console.WriteLine("testRef: " & arr(0, 0) & "!")
End Sub C# code: engine.AddHostObject("zp", new VBClass());
engine.Execute(@"
Option Explicit
dim timeGap(1,1)
timeGap(0,0)=37
timeGap(0,1)=1
timeGap(1,0)=39
timeGap(1,1)=2
Sub Main
zp.testArr 5, timeGap
zp.print timeGap(0,0)
End Sub
Main
"); Please let us know if this solution works for you. Thanks again! |
Thank you again for your guidance. |
@ClearScriptLib I made a slight modification to the format and noticed another issue
C# Code
output : |
Hi @Rison-Hub, Because Public Sub testByRef(ByVal OutStr As Integer, ByRef iShow As Object)
iShow = iShow + 5
Console.WriteLine("testByRef: " & iShow & "!")
End Sub And then: engine.Execute(@"
Option Explicit
dim ByReftest
ByReftest = host.newVar(object, 3)
Sub Main
zp.testByRef 5, ByReftest.ref
zp.print ByReftest
End Sub
Main
"); Output:
Note that the situation above with the array is different because .NET arrays are reference types, meaning that you can modify the contents of a .NET array without modifying the variable that holds a reference to it. In this case, even though the Good luck! |
@ClearScriptLib I need to integrate with HALCON, where HObject is a reference type.
C# Code
The value passed to display_open is the return value of EmptyHObj, not the value read from New_ReadImage. However, if you use the following code, the value passed is correct. VB Code
C# Code
|
Hi @ClearScriptLib, The behavior you're seeing is correct. According to the HALCON documentation, the static void ReadImage(out HObject image, HTuple fileName) Note that In this case, Therefore, you don't have to call Cheers! |
Thank you again for your guidance. |
VBS CODE:
Option Explicit
Sub Main
dim reftest
reftest=0
zp.testRef 5,reftest
zp.print reftest
End Sub
Main
VB.NET CODE:
Public Class VBClass
Public Sub Print(ByVal OutStr As Object, ByVal Optional iShow As Integer = 1)
Console.WriteLine("OutStr: " & OutStr & "!")
End Sub
End Class
C# Code:
private void button10_Click(object sender, EventArgs e)
{
var VBscript = new VBClass();
using (var engine = new VBScriptEngine())
{
engine.AddHostObject("zp", VBscript);
var scriptCode = File.ReadAllText("D:/Script/abc.vbs");
engine.Execute(scriptCode);
The text was updated successfully, but these errors were encountered: