using tstringlist in function params

how i can use tstringlist in function params

function e_test_strs (var qstrs : tstringlist; qstr : string) : boolean;
begin
qstrs.add(qstr);
end;

in define metheod i use :
fscripter.DefineMethod('e_test_strs',2,tkinteger,nil,script_VM,false,2);

in script_VM, TatVirtualMachine i use :
procedure c_script.script_VM(AMachine: TatVirtualMachine);
var qstra : string; inta : integer; qstrs : tobject;
begin

With AMachine do begin

If lowercase(CurrentMethodName) = 'e_test_strs' then begin
qstrs := GetInputArgasobject(0);
ReturnOutputArg(e_test_strs( qstrs, GetInputArgAsString(1)));
SetInputArg(0,ObjectToVar(qstrs));
end;

that compile, but i get error when i try to use this function

Which error do you get? Are you pretty sure this is the code you are using? It should not even compile in Delphi, since e_test_strs expects a TStringList object and in your script_VM method it's declared as TObject.

if i declare qstrs : tstringlist; -> my program will not compile.

if i declare qstrs : tobject; -> program compile, but get error : method expects argument 0 as variable reference position : 3,28

my script is :
begin
qstrs := tstringlist.create;
e_qstrs_test(qstrs, 'test');
qstrs.destroy;
end

how i can define my function in script_vm :
function e_test_strs (var qstrs : tstringlist; qstr : string) : boolean;

Which "program" will not compile? Obviously you need to declare it as TStringList. I suggest you create a minimum project that reproduces the problem and send it to us. It's more straightforward than discussing a source code that doesn't even seem to compile.

minimum project
teststringlist.zip (28.7 KB)

If I understand what you are trying to say you are doing. And from looking at what is in your sample project. (I have not compiled the code.) The main reason you are getting the error: method expects argument 0 as variable reference position : 3,28. Is because you did not fully define that parameter 0 in e_test_strs method, which is var gstrs: tstringlist, as a parameter that is being passed By Reference.

But, there seems to be another problem with your sample code. You have defined the e_test_strs function to return a Boolean value. But, the actual function does not actually return a value at all. As such the project should not compile at all. The compiler should with an error message about a value not being returned.

And, I am not sure if TMS Scripter can have a method that is a function where a value is returned to the user. And to set the value of a parameter passed to the method By Reference. Wagner Landgraf can verify that you.

And one last thing. Why are you trying to create a procedure, or function, to add a string to a TStringList? Why not use the predefined Class Libraries to your project's Uses clause, specifically ap_Classes. And you will have full function from within TMS Scripter for use of TStringList and its methods.

But, if you wish to create your own methods to work with TStringList. Then follow what I have below.

So, in order to fix your sample project so that it should work. You need to add the SetVarArgs sub-method to your DefineMethod statement. You can read up on what SetVarArgs does by reading the comments at line 4747 in the atScript.pas file.

But, basically your DefineMethod for the e_test_strs should look similar to the following:

  fscripter.DefineMethod('e_test_strs',2,tkinteger,nil,pteststrings.Form1.script_VM,false,2).SetVarArgs([0]);

That is it. But, since you are not actually returning a Boolean value from the e_test_strs function to be sent to the VM. I would personally have the script_VM procedure do the following:

 If lowercase(CurrentMethodName) = 'e_test_strs' then begin
  qstrs := GetInputArgasobject(0);
  TStringList(gstrs).Add(qstr);
  SetInputArg(0,ObjectToVar(qstrs));
 end;

But, if you really want to have the adding of a string to the StringList to take place within a separate function, like you had originally coded. Then you have to have the function actually return a value. And I would change the following lines:

Change lines 29, 43, 54 to the following:

Line 29-

function e_test_strs(var qstrs: tstringlist; qstr: string): boolean;

Line 43-

var qstra : string; inta : integer;    qstrs : tstringlist;

Line 54-

  qstrs := TStringList(GetInputArgasobject(0));

Line 64-

  fscripter.DefineMethod('e_get_app_folder',0,tkVariant,nil,pteststrings.Form1.script_VM,false,0);

Then change e_test_strs function to be:

function e_test_strs(var qstrs: tstringlist; qstr: string): boolean;
begin
//if assigned(qstrs) = false then  qstrs := tstringlist.Create;
  qstrs.Add(qstr);
  // add in a statement, or several statements, that will have the function return a value
end;

But, if you do not wish to return a value from the function. Then I would highly suggest that you change the function to be a procedure instead.

Since it seems that you normally worked with C#, or C++. There is something I want to mention to you. Unlike C#, and other programming languages, that require you to define the use of a procedure, or function, within another method. (Like the DefineMethod in TMS Scripter.) In Delphi, or Pascal, when you define your DefineMethod statement. you only need to use the name of the procedure, or function, provided the procedure and the DefineMethod is in the same Unit (or file).
So, your DefineMethod statements should look like the following:

  fscripter.DefineMethod('e_get_app_folder',0,tkString,nil,script_VM,false,0);
  fscripter.DefineMethod('e_test_strs',2,tkVariant,nil,script_VM,false,2);

1 Like

fscripter.DefineMethod('e_test_strs',2,tkinteger,nil,pteststrings.Form1.script_VM,false,2).SetVarArgs([0]);
resolve the problem. ------------> (SetVarArgs([0]); +++ )

thanks Hagin Michael

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.