Passing array by reference

Is it possible to pass an array by reference to an ADK plug-in function (in C++) ?
I want to pass an array to the function from my AFL, change values inside the function and then plot it from the AFL.
I am aware that the ADK returns an array, but I would like to know whether I can modify the values passed array ? By passing multiple arrays, my function can calculate and return different arrays - and avoid multiple functions.

myArr = (H + L) / 2;
myFuncResult = MyFunctionA(myArr);
Plot(myArr, "myArr", colorRed);

Another example

myArr1 = (H+L) / 2;
myArr2 = (O + C) / 2;
myFuncResult = MyFunctionB(myArr1, myArr2);  // Here both myArr1 and myArr2 may be modified.
Plot(myArr1, "myArr1", colorRed);
Plot(myArr2, "myArr2", colorGreen);

1 Like

First: I am against using DLLs to rewrite your AFL. It takes lots of work (and time and experience) for little or no benefit at all. Array AFL code runs faster than your DLL because DLLs are locked out by criticial section as explained many times. DLLs make sense ONLY for rewriting tight (possibly nested) loops. No other use makes sense. If you have time-critical double nested loop that requires billion iterations - sure go for DLL then, but in other cases it has no merits.

Having said that, to answer your question in single sentence: If you want to modify variables from DLL you can do so using gSite.SetVariable()

More technical background: No you can not directly modify elements of array passed as argument by value because the very same array may be used by multiple variables. AmiBroker does NOT copy arrays on assignments.
For example if you write

x1 = x2 = x3 = H + L; // only single memory block is allocated here

then all three x1, x2 and x3 will actually point to the very same allocated memory block, unless you modify one of them in AFL:

x1 = x2 = x3 = H + L; // only single memory block is allocated here
// this will magically behind the scenes "disconnect" x1 from x2 and x3 
// and increase only x1
x1++; // x1 has now new array allocated, x2 and x3 will remain connected to old block

Dozens of things like that make AmiBroker so fast (in this example array assignment costs nothing).

So I can repeat: If you want to modify variables from DLL you can do so using gSite.SetVariable()

In BETA version (6.29) you can pass variables by reference but this is not documented in ADK and I am reluctant to document this because experience and support history shows that it is likely to be used incorrectly and cause problems (access violations) when used by inexperienced.

By the way: there are lots of threads that discussed that already in great detail, so next time please do the forum SEARCH first:

https://forum.amibroker.com/search?q=setvariable

Some of these threads contain important information that I did not cover in this reply (who wants to repeat himself?) so please do read all threads listed by search above.

5 Likes

Tomasz, thank you for the explanation.

I am using gSite.SetVariable (to set an array in the AFL). It works.