PDA

View Full Version : Pass ATPA to c++ plugin



bg5
11-07-2013, 10:42 AM
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
11-07-2013, 11:38 AM
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
11-07-2013, 12:42 PM
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
11-07-2013, 04:41 PM
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
11-07-2013, 09:40 PM
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);

http://puu.sh/5bJrI.png

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
11-08-2013, 01:05 AM
aka a vector ... ...

bg5
11-08-2013, 01:41 AM
Solved it:)

http://puu.sh/5bNmS.png

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
11-08-2013, 07:22 AM
Correct me if im wrong... but isnt... high(arr) just...
function high(a : arraything): Int32 (or something);
begin
result := length(a) - 1;
end;

superuser
03-16-2016, 01:55 PM
hi i am new in programming world, and my college assign me c++ as essential programming language, so can anyone tell me where can i get some advance classes, i just see this post and believe me i never use high() function in c++. :-(

Try https://isocpp.org/faq for starters.

slacky
03-16-2016, 04:01 PM
Correct me if im wrong... but isnt... high(arr) just...
function high(a : arraything): Int32 (or something);
begin
result := length(a) - 1;
end;
Okay, so I'll just correct you then: FPC doesn't store the length of the array, it stores "high". So it's to other way around:

High := (PSizeInt(arr)-SizeOf(SizeInt))^;
Length := High+1;


Delphi however stores the Length.
And before the `Size field` in the array header, there is a `refcount field`.

Lape does whatever FPC or Delphi does depending on what it's compiled with.

Keep in mind that SizeInt is not the same as Int32, its size depends on the maximum addressable memory on the current arch. So on x86-64, with 64bit Simba it's Int64. Equivilant to size_t in C++.

Kasi
03-16-2016, 05:23 PM
hi i am new in programming world, and my college assign me c++ as essential programming language, so can anyone tell me where can i get some advance classes, i just see this post and believe me i never use high() function in c++. :-(

Pretty buried thread man. If you need help with something, make a new thread. Don't bump an old fractionally related thread.

size_t in c++ is implementation defined. It is always unsigned though, or should always be unsigned. slacky; is slightly incorrect. I would say size_t would be uint32/64 depending on the platform.

slacky
03-16-2016, 06:08 PM
size_t in c++ is implementation defined. It is always unsigned though, or should always be unsigned. slacky; is slightly incorrect. I would say size_t would be uint32/64 depending on the platform.
Indeed, I am. Tho I do think a signed int-type with the same (platform dependent) size as size_t would be correct afaict. But as c++ is not my world, idk if there is any predef type like that :p

Brandon
03-22-2016, 01:07 AM
Indeed, I am. Tho I do think a signed int-type with the same (platform dependent) size as size_t would be correct afaict. But as c++ is not my world, idk if there is any predef type like that :p


Has the same in both C and C++ and I've seen these in Pascal as well:

intmax_t -- Max signed integer for whatever platform you are on.
intptr_t -- Signed integer that has enough space to hold a pointer.
uintmax_t -- Max unsigned integer for whatever platform you are on.
uintptr_t -- Unsigned integer that has enough space to hold a pointer.

http://en.cppreference.com/w/cpp/types/integer
https://github.com/graemeg/freepascal/blob/master/rtl/netwlibc/libc.pp#L55


In C, they are found in <stdint.h> and in C++ <cstdint>.


Though, I'm not sure the difference between IntPtr in Pascal and SizeInt. Possibly synonymous with the C types.