SRL Archive - C/C++ Help and Tutorials

Pass ATPA to c++ plugin


bg5

2013-11-07 05:42:20

C++ doesn't have something like High(), so when you pass dynamic array, you need to pass it's length too.
So when I want to pass TPA to c++ plugin my function inside looks like:

void __declspec(dllexport) DoSomethingWithTPA (POINT TPA[],int HighOfTPA)

But what if I want to pass 2d array like ATPA? I would need pass length of all sub-arrays too, like:

void __declspec(dllexport) DoSomethingWithATPA (POINT ATPA[][],int HighOfATPA, int HighsOfSubTPAs[])

It's terrible, isn't it? What's the better way to do it?

Sin

2013-11-07 06:38:09

IIRC by a dynamic array you mean a vector, so can't you just use (vector.size()-1)? That returns the amount of elements minus 1, which will be the last element in the array.

bg5

2013-11-07 07:42:48

From: Sin
IIRC by a dynamic array you mean a vector, so can't you just use (vector.size()-1)? That returns the amount of elements minus 1, which will be the last element in the array.


Uhm,no, it's not a vector. I was considering using vector, but I don't know much c++ and I'm kinda lost. And for 2d array I would need 2d vector I think?

Also I'm not sure if I can fit Simba's array into c++ vector, vector is a class and appart from data array it contains some additional stuff, when in the method I'm curently using I just pass a pointer to a raw data stream, I think.

Enslaved

2013-11-07 11:41:27

You would need to define the vector any way, and "push_back" each value, which gives you the same error as using a predefined array. The way to make 2d array in c++ would be to set a pointer to an array that you initialize. Alternatively you can try force feeding the array until it hits an runtime error through which you would just use the "try, catch" method when it causes an exception.

With all of that being said, why not just use a wrapper for the first function if you think passing arguments to it looks ugly??

bg5

2013-11-07 16:40:32

From: Enslaved


With all of that being said, why not just use a wrapper for the first function if you think passing arguments to it looks ugly??


I don't have problem with first(TPA) function, maybe it looks ugly, but I'm ok with that. However for second(ATPA) function wrapper would be necessery, not just because of estetic reason. You would need to prepare list of lengths of all subTPAs in ATPA (HighsOfSubTPAs in plugin). So I would need wrappers for every function using 2d arrays.
It's not solution for me, because I'm actually trying to keep my plugin independent from any .simba include.

Alternatively you can try force feeding the array until it hits an runtime error through which you would just use the "try, catch" method when it causes an exception.


Could you explain it a bit deeper?



I wonder how Pascal knows the length of an array? As array is generated in Simba, maybe it's possible to use the same method in plugin?







Edit:

Well, after some reseach I've found how dynamic ATPA is alocated in memory.

This is what happens in memory, when you do e.x this:

SetLength(ATPA,2);
SetLength(ATPA[0],8);
SetLength(ATPA[1],6);

Basically @ATPA points to address of an array, which contains pointers to firsts elements of subTPAs. The High of array (length-1) is always contained in the word before first element of the array.

…So whats left is to make in c++ array handler based on this structure:wacko:

Enslaved

2013-11-07 20:05:37

aka a vector … …

bg5

2013-11-07 20:41:50

Solved it:)


Here is a code (a bit messy) if someone were interested:

extern "C" void __declspec(dllexport) ATPAtest (int *ATPA)
{
ATPA = ATPA -1;
int highATPA = *ATPA;
int* highs=new int[highATPA+1];
std::cout<<" high of ATPA"<<highATPA<<"\n";
ATPA = ATPA+1;
int i,j;
int *TPA;
POINT *P;
POINT PP;
for (i=0;i<=highATPA;i++)
{
TPA = (int*)*ATPA;
TPA = TPA-1;
highs[i] = *TPA;
TPA = TPA+1;
std::cout<<" high of ATPA["<<i<<"] :"<<highs[i]<<"\n";

P = (POINT*) TPA;
for (j=0;j<=highs[i];j++)
{
PP = *P;
std::cout<<"ATPA["<<i<<"]["<<j<<"] "<<PP.x<<","<<PP.y<<"\n";
P=P+1;
}
ATPA = ATPA+1;
}
}

static char* exports[] =
{
(char*)"ATPAtest",(char*)"procedure ATPAtest(ATPA:T2DPointArray);"
};

Turpinator

2013-11-08 02:22:06

Correct me if im wrong… but isnt… high(arr) just…
function high(a : arraything): Int32 (or something);
begin
result := length(a) - 1;
end;