*Var AND *(&Var) with gSite.GetStockArray

I have left C/CC++ coding long back some where in 2001, No doubt that I need to refresh it.
But now I found the C/C++ interesting when Amibroker has nicely and safely played with array and pointers, unions and structures.
I have one doubt with the consideration of following line.

To the best of my memory and if I am not wrong, *float O is a Pointer pointing to some location of memory Address AND *(&O) is the value (Content) stored at that address.

CAN following line avoid multiple calls of gSite.GetStockArray( 0 ) if I want to copy values (content ) stored at *O without disturbing it, in case I change values stored at *xO, *yO, zO at later stage?
Can values (content) stored at *O be copied to *xO, *yO and *zO directly ?

//The code
float *O = gSite.GetStockArray( 0 ),*xO = *(&O) , *yO = *(&O) , *zO = *(&O);
AmiVar xA = gSite.AllocArrayResult() , xB = xA;

This is not generally true. That would only work if you referred to single float value (4 bytes) via pointer, but in AmiBroker pointer to float typically points to ARRAY of floats and you can't copy entire array via *ptr in single assignment in C. Copying arrays in C typically involves using memcpy.

Thanx for quick reply ....
So the only way is to use repeated calls of gSite.GetStockArray( 0 ) right ?
or memcpy will be faster ? What do you suggest ?

No. You are mixing two things. One thing is copying pointer (the one that you are getting via GetStockArray(). The other thing is copying content (array). These two are two completely different things. You can copy and use pointer to READ data as many times as you want. But if you want to MODIFY data you have to allocate memory for result and use allocated memory. GetStockArray is giving you READ-ONLY memory. And don't worry about the speed with pointers. GetStockArray is a super thin function that is pretty much equally fast as using pointer as it gets inlined by compiler anyway.

2 Likes

Your are right, I also tried a pointer to pointer in code DLL Compiled but returned zero in afl....
Neither it worked nor crashed...
Due to AFL I remember Clipper of 1990s on DOS. Clipper programmers were allowed to work with multidimensional arrays but there were no pointers , unions and structures like C/C++. There was MSC6.0 support for LARGE MODEL external third party Libraries which was used for additional development.
.
<>
it appears Amibroker has some Assembly Code with C/C++ :slightly_smiling_face:
.
Now I will use gSite.GetStockArray only instead of trying to make copy of its output.
Thanx once again.

Wiil this be a right way to CALL AMA (C,0.65) in DLL ?

int nSize = gSite.GetArraySize();
AmiVar result = gSite.AllocArrayResult(), factor =gSite.AllocArrayResult(), arg[2];
float *Close = gSite.GetStockArray( 3 );

arg[ 0 ].type = VAR_ARRAY;
arg[ 0 ].array =Close;
arg[ 1 ].type = VAR_ARRAY;

for(int i = 0; i < nSize; i++)
    {
	factor.array[i]=0.65; // all elements with same value i.e. 0.65
}

arg[ 1 ].array = factor.array;
r2 = gSite.CallFunction( "AMA", 2,arg); //  AMA(C, 0.65 );
     gSite.SetVariable("xClose",r2);

You should not be using CallFunction at all. Plugin interface is NOT for rewriting AFL code.
I explained it here: How to get result for PriceVolDistribution in plugin? and here 5 reasons why you should NOT write DLLs

@Tomasz

Plot(AMA(C,.65),"",colorRed,styleLine);
output[0]=0;
input=C;
factor=.65;
for( i = 1; i < BarCount; i++ )
{
output[ i ] = factor[ i ] * input[ i ] + ( 1 - factor[ i ] ) * output[ i - 1 ];
}
Plot(output,"",colorgreen,styleLine);
.
AMA logic / formula in AFLand AMA Function are giving same output.
so in DLL I can use this logic instead of CallFunction.
Now if I pass some other average or array in C/C++ to get AMA's out put do i need to set the first element of that array to 0 like AFL logic ?bb

AMA Function converted to C, tested and it is working properly
AmiVar VxAMA( int NumArgs, AmiVar *ArgsTable )
{
//AMA C Code

AmiVar output = gSite.AllocArrayResult();
float factor =  ArgsTable[ 1 ].val; // kept as float and not an array
float *input = ArgsTable[0].array;
output.array[0]=0;

int nSize = gSite.GetArraySize(),i;	                                        
i= SkipEmptyValues( nSize,input , output.array ); // use code given with ADK
		
for(i=1;i<nSize;i++)
{
	
	output.array[ i ] = factor * input[ i ] + ( 1 - factor ) * output.array[ i - 1 ];
    }  

return output;

// Function Table Entry
FunctionTag gFunctionTable[] = { "xAMA", { VxAMA,1, 0, 1, 0, NULL }}

As @Tomasz said before

Also all these posts violate forum rules.

When posting the formula, please make sure that you use Code Tags (using </> code button) as explained here: How to use this site.

Using code button

Code tags are required so formulas can be properly displayed and copied without errors.

You should not be writing DLLs because you C/C++ knowledge is too weak.
DLLs are NOT for you.

Your code is wrong.

Output of AMA must NOT be initalized with zero. It should be first non-null value of input array:

i = SkipEmptyValues( nSize,input , output.array ); // use code given with ADK

if( i < nSize )
{
 output.array[ i ] = input[ i ];
 i++;
 for(;i<nSize;i++)
 {
   output.array[ i ] = factor * input[ i ] + ( 1 - factor ) * output.array[ i - 1 ];
 }
}
2 Likes

Deat @Tomasz
Thanx for Reply.
I am learning ADK and now I am not in touch of C/C++ which I have left 15-20 years back.
But I am impressed with Amibroker's ADK/API methods which has encouraged me to polish my knowledge again. Actually it is easy to start with C again because of predefined enums, unions and structures in Amibroker's ADK Header Files.
.
What I have noted from your earlier advice that not to use CallFunction without reason, so I was trying to write AMA() in C.
But If my C Code is wrong how it gives correct result of inbuilt AMA function of Amibroker ?
I will also take care to post Code with provision of </> Button. I was trying to correct it but post was not published.
-Regards

You assume that it would give correct result(s).
But your assumption is incorrect.

15


SOURCE ARRAY (inserted into AMA function, take careful look):
16


Now that one used with incorrect AMA code (initialized with zero and not taking care of NULL):

Oopsy...

17

And....
19


Now correct output of AMA:

18

Still thinking it is the same result?

You can check yourself without C-code

1 Like

Dear fxshrat
Thanx for that help.

  1. My old C code xAMA, 2) the in built AMA Function and 3) the corrected xAMA code by TJ ,all 3 were giving same output, so I was not able to find out the difference, but when I saw chart from beginning there was as an issue due to output.array[0]=0;
    So i corrected it as told by TJ.
    image_2020-12-02_091826

Actually I was doing this for Another code given in examples that uses in build AMA in C


AmiVar vXVarWild( int NumArgs, AmiVar *ArgsTable )
{
	int nSize = gSite.GetArraySize();
	float * Array= ArgsTable[ 0 ].array;
	float * nRange=   ArgsTable[ 1 ].array;

	AmiVar result = gSite.AllocArrayResult();
	AmiVar nPer = gSite.AllocArrayResult();

	for(int i=0;i<nSize;i++)
	{
		nPer.array[i]= 1 / nRange[i];
	}

	AmiVar arg[ 2 ];
	arg[ 0 ].type = VAR_ARRAY;
	arg[ 0 ].array = Array; 
	arg[ 1 ].type = VAR_ARRAY;
	arg[ 1 ].array = nPer.array; 

// return result = gSite.CallFunction( "AMA", 2, arg ); 
 return result = VxAMA(2,arg );
//
}

In the attached image of my old code, it is affecting xAMA due to output.array[0]=0;

It is not my job to explain what other people's (your) C++ code is doing and why your C++ is different.

To get better understanding of what is happening in your code and how functions work, use advice given here: How do I debug my formula?

As has been written a number of times in this thread Plugin interface is NOT for rewriting AFL code. *Var AND *(&Var) with gSite.GetStockArray - #7 by Tomasz