PA_ExecuteMethod

4D - Documentation   Français   English   German   4D Plugin API, Command Theme List   4D Plugin API, Command Alphabetical List   Back   Previous   Next

version 2003


PA_ExecuteMethod (toExecute; len)

ParameterTypeDescription
toExecutechar *Text of the statement to execute
lenlongLength of toExecute

Description

The routine PA_ExecuteMethod executes the expression toExecute, given its length in len.

This works exactly like the 4th Dimension command EXECUTE. See the 4th Dimension Language Reference manual (one line of code, etc.).

Any valid expression can be executed, provided that it is a command (4D command, project method, statement). For statements that return a result, use PA_ExecuteFunction.

Examples of 4D statements

1. This line of code is a valid statement, calling a valid 4D command, passing a valid parameter :

   ALERT ("I've been called from an Extension")

2. The line of code below is a valid 4D statement as well:

   ` This will call the 4D project Method provided that it exists
   TheProjectMethod (1;"abc")

3. The line of code below is not a valid 4D statement:

   TheProjectMethod (1,"abc")

The line contains a syntax error: a comma instead of a semi-colon. In this case, the 4D syntax error code will be returned by PA_GetLastError .

When to use PA_ExecuteMethod

PA_ExecuteMethod allows the 4D plug-in to call any piece of 4th Dimension code. The 4D plug-ins can, for example, use PA_ExecuteMethod to call a 4th Dimension command that is not available in the 4DPluginAPI.

A plug-in can ask the user to execute its own formula, using the PA_FormulaEditor routine (see example below).

A more powerful use of this entry point is the implementation of callbacks to 4th Dimension project Methods written by the 4D developers using the plug-in. This entry point as well as the other "Execute" entry points are used by 4D plug-ins such as 4D Write.

While using 4D Write, a user may want to customize the behavior of a 4D Write menu item. 4D Write provides a way to do this using the WR ON COMMAND command. This 4D Write command expects two parameters, the address of the 4D plug-in area, and the name of the 4D Method to be called when a menu is chosen.

If the 4D Write area is named wrArea and the Menu Method is named wrMenuProc, the Method would be called as:

WR ON COMMAND (wrArea;"wrMenuProc")

Once this call is made, the 4D Write module internally keeps track of the name passed for this particular area. Then, each time a menu item is selected in this area, 4D Write calls the 4D Method using PA_ExecuteMethod.

In addition, the 4D Write documentation indicates that the 4D Method receives two parameters: a long integer specifying the area and a long integer specifying the menu item. If the value of the 4D plug-in area address for wrArea is, for example, 25405088 and the Open menu item is chosen from the File menu, 4D Write executes the following 4D statement: wrMenuProc(25405088;102). In this statement, the values are received in the parameters $1 and $2 that are declared accordingly.

When not to use PA_ExecuteMethod

Before executing the method statement, 4th Dimension needs to check that its syntax is valid, otherwise unpredictable results may occur. In other words 4D invokes its interpreter to parse, validate, and tokenize the text. Then, if it is valid, the tokenized form is executed. Consequently, even if the database is running compiled, it will execute the statement call at the speed of an interpreted database. If a 4th Dimension Method is called, the method will run compiled, but the call itself is interpreted.

In the above 4D Write example, this is not really important since the interpreted execution time is very short compared to the time the user spent choosing the menu item. On the other hand, if it is used to call a formula several hundred or thousands of times inside a loop, the interpreted execution time will become significantly greater than that of a similar compiled execution.

Consequently, when using this routine, the 4D plug-in developer must try to balance the functionality it adds with the inefficiency it introduces when compared to compiled code. In this regard, there are other ways of executing 4th Dimension code from within 4D plug-ins, such as pre-tokenizing the statement, execute a method by its ID, etc.

Is the 4D plug-in routine re-entrant when calling PA_ExecuteMethod?

When calling PA_ExecuteMethod the 4D plug-in must be ready for anything. Let's look at an example.

A 4D plug-in is written which implements the following features:

· A 4D plug-in area called %X AREA,

· A 4D plug-in routine called X ON CLICK,

· A 4D plug-in function called X Get contents.

As an example X ON CLICK will allow the user to specify a 4D Project Method to be called each time a click occurs in an X area. The syntax of X ON CLICK would be: X ON CLICK (Which X Area ; Method to be called)

The routine X Get contents returns the contents of an X area, whatever these contents may be.

For this example we will call it text. The syntax of X Get contents would be: X Get contents (Which X Area) -> Text expression

Once this is implemented we can imagine a situation in which a 4D Form contains two X areas, Xa and Xb.We can also imagine a 4D Project Method associated with a click on Xa written as:

X ON CLICK (Xa;"X DO SOMETHING")

Finally, it is not forbidden to use a 4th Dimension project Method such as:

   ` X DO SOMETHING global Method
   ALERT (X Get contents (Xa) + X Get contents (Xb))

With this configuration in mind, if Xa contains "Hello " and Xb "World!" the user would get an Alert with "Hello World!" for each click on Xa. This is as expected.

New functionality is added after a few weeks. The 4D plug-in now saves the location and the time of a previous click in the private data of each X area. Also a new routine is added. We will call it X ON DOUBLE CLICK. At this point the user discovers that the 4D plug-in no longer works. Either the double-clicks are not reported when they should be or they are reported when they should not be.

The plug-in developer starts tracing the code and discovers that "occasionally" the click information is saved in an X area that is different than the area expected. In addition, the developer finds that in the example described above, the information on the click in Xa is always saved in the private data of Xb! Finally the developer finds the culprit: all of the Extension code was relying on a 4D plug-in area address copied by a package routine into a Pascal or C global variable (myArea for example).

The sequence of events:

1. A click occurs in Xa, 4th Dimension calls %X Area (and the 4D plug-in sets the global variable myArea equal to Xa).

2. The Extension calls the subroutine in charge of the X Area's.

3. The 4D plug-in detects Xa has a click-initiated Method named X DO SOMETHING.

4. The 4th Dimension Method calls the 4D plug-in to get the contents of Xa (and the 4D plug-in sets the global variable myArea equal to Xa).

5. The 4th Dimension Method calls the 4D plug-in a second time to get the contents of Xb (and the 4D plug-in sets the global variable myArea equal to Xb).

6. Finally the 4D Plugin saves the click information in the current area referenced by the global variable myArea, which is incorrectly set to Xb because of a re-entrant call.

Conclusion

Although the multi-tasking environment of 4th Dimension already forces the 4D plug-in to be re-entrant, the use of PA_ExecuteMethod enforces this point.

Examples

(1) Execute a 4D command, a project method, and a valid expression :

   void SampleExecuteSomething ()
   {
      char   aCommand[] = "CLEAR CLIPBOARD"; // using C strings here
      char   aMethod[] = "MySupermethod(1, 2, 3)"; // this is a valid method of the database
      char   anExpression[] = "aValidVariable:=10";

      PA_ExecuteMethod(aCommand, strlen(toExecute));
      PA_ExecuteMethod(aMethod, strlen(aMethod));
      PA_ExecuteMethod(anExpression, strlen(anExpression));
   }

(2) Execute a user specific formula:

   void UserFormula ()
   {
      char   *formula;
      long   len = 0;

      formula = malloc(32000);
      if(PA_FormulaEditor(0, formula, &len))
         PA_ExecuteMethod(formula);
      free(formula);
   }

See Also

PA_ExecuteFunction, PA_ExecuteMethodByID, PA_ExecuteTokens, PA_FormulaEditor, PA_GetMethodID.

Error Handling

Use PA_GetLastError to see if an error occurred


4D - Documentation   Français   English   German   4D Plugin API, Command Theme List   4D Plugin API, Command Alphabetical List   Back   Previous   Next