Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: What is meant of double asterisk, ArrayOf? I get Division by Zero?


This question is answered.


Permlink Replies: 12 - Last Post: Feb 10, 2018 1:01 PM Last Post By: roca robin Threads: [ Previous | Next ]
roca robin

Posts: 140
Registered: 9/10/06
What is meant of double asterisk, ArrayOf? I get Division by Zero?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 6, 2018 12:25 PM
Can someone point me where is the problem of the lines of code?
I get Division by Zero?

//..Code from vc12 which make .DLL after buid! //..or a DLL wrapper

I_API void __stdcall NumberCallerDraw(TNumberCaller* dcaller, IplImage** dimage, int* dnum)
{
//
}

I_API void __stdcall NumberCallerSave(TNumberCaller* dcaller, char* fn)
{
//
}

//..with c++ Builder I interface it like this,

typedef DynamicArray< IplImage* > ArrayOfImage;
typedef DynamicArray< int > ArrayOfInteger;

extern "C" __declspec(dllimport) void __stdcall NumberCallerDraw(const void* dcaller,
ArrayOfImage dimage, ArrayOfInteger dnum);

extern "C" __declspec(dllimport) void __stdcall NumberCallerSave(const void* dcaller,
char* filename );


//..Implementation,
//
//..This procedure WORKS GOOD, it can saved declared filename to any drive.
void __fastcall TNumberCaller::save(const String filename )
{
NumberCallerSave( TnumberCaller::oPointer, ((AnsiString) filename ).c_str());
}

//..This procedure IS NOT WORKING, it popup error when run..,
void __fastcall TNumberCaller::draw(ArrayOfImage dimage, ArrayOfInteger dnum )
{
NumberCallerDraw( TnumberCaller::oPointer, dimage.Length, dimage, dnum );
}


I Use them like this:

ArrayOfImage fimages;
ArrayOfInteger fnumbers;

int ndex;

ndex = sqliteQuery->RecordCount; ///..7 records only for testing

fimages.set_length(ndex);
fnumbers.set_length(ndex);

IplImage* dbimage;

ndex = 0;

while (!sqliteQuery->Eof){

imagedrawn= new TBitmap();

//codes here...

dbimage = cvCreateImage(cvSize(640,480), IPL_DEPTH_8U, 1);
dbimage = Bitmap2IplImage(imagedrawn); //..Works very good...

fimages[ndex] = dbimage;
fnumbers[ndex] = ndex;

xdbimage = new TBitmap();
IplImage2Bitmap(fimages[ndex], xdbimage); //..To find out its working GOOD.
imgCallerLocation->Picture->Assign(xdbimage); //..DISPLAYS the last image from the records..Tested Good, no issues.

ndex+=1;
sqliteQuery->Next();
}

//..Codes here..

TNumberCaller *tcallerid;
tcallerid = new TNumberCaller(); //..Creates New Caller..code line no problem.tested.
tcallerid->createNumberCaller(1,100.1); //,,Creates New Number..code line no problem.tested.

tcallerid->save(_y_filename_); //..Saves the Caller on a disk..code line no problem.tested.

//..No Error BEFORE below the line of Code. v

//..IF I comment that line below? there will be NO popUp Error Message.
tcallerid->draw(fimages, fnumbers); //..Draw the location of the Caller..
code NOT WORKING...PopUP ERROR Message say "External Exeption E06D7363" or /"division by zero"

@Ted and @Alex
thanks for helping, this is the continuation of my problems, lol

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 6, 2018 2:21 PM   in response to: roca robin in response to: roca robin
roca robin wrote:
Can someone point me where is the problem of the lines of code?
I get Division by Zero?

DynamicArray<IplImage*> and IplImage** are not the same thing. DynamicArray<int> and int* are not the same thing.

Your C++Builder code can use DynamicArray variables for purposes of memory management, but DO NOT declare parameters of imported DLL functions as being DynamicArray on the C++Builder side. For interop purposes, you need to use the same (or at least equivalent) declarations in both compilers.

In fact, your C++Builder code shouldn't even compile, because the DLL's NumberCallerDraw() function only has 3 parameters, but you are trying to pass it 4 values in you C++Builder code.

Try something more like this on the C++Builder side:

typedef DynamicArray< IplImage* > ArrayOfImage;
typedef DynamicArray< int > ArrayOfInteger;
 
extern "C" __declspec(dllimport) void __stdcall NumberCallerDraw(const void* dcaller, IplImage** dimage, int* dnum);
extern "C" __declspec(dllimport) void __stdcall NumberCallerSave(const void* dcaller, char* filename );
 
void __fastcall TNumberCaller::save( const String &filename )
{
    NumberCallerSave( TnumberCaller::oPointer, AnsiString(filename).c_str() );
}
 
void __fastcall TNumberCaller::draw( ArrayOfImage &dimage, ArrayOfInteger &dnum )
{
    NumberCallerDraw( TnumberCaller::oPointer, (dimage.Length > 0) ? &dimage[0] : NULL, (dnum.Length > 0) ? &dnum[0] : NULL );
}
 
...
 
ArrayOfImage fimages;
ArrayOfInteger fnumbers;
 
fimages.Length = sqliteQuery->RecordCount;
fnumbers.Length = fimages.Length;
int ndex = 0;
 
try
{
    while (!sqliteQuery->Eof)
    { 
        imagedrawn = new TBitmap;
        try
        {
            //codes here...
            fimages[ndex] = Bitmap2IplImage(imagedrawn);
            fnumbers[ndex] = ndex;
            ++ndex;
        }
        __finally
        {
            delete imagedrawn;
        }
 
        xdbimage = new TBitmap;
        try
        {
            IplImage2Bitmap(fimages[ndex-1], xdbimage);
            imgCallerLocation->Picture->Assign(xdbimage);
        }
        __finally
        {
            delete xdbimage;
        }
 
        sqliteQuery->Next();
    }
 
    ...
 
    TNumberCaller *tcallerid = new TNumberCaller;
    try
    {
        tcallerid->createNumberCaller(1,100.1);
        tcallerid->save(_y_filename_);
        tcallerid->draw(fimages, fnumbers);
        ...
    }
    __finally
    {
        delete tcallerid;
    }
}
__finally
{
    for (int i = 0; i < ndex; ++i)
        cvReleaseImage(&fimages[ndex]);
}


Alternatively:

struct TIplImage
{
    IplImage *Image;
 
    TIplImage() : Image(NULL) {}
    ~TIplImage() { cvReleaseImage(&Image); }
};
 
typedef DynamicArray< TIplImage > ArrayOfImage;
 
extern "C" __declspec(dllimport) void __stdcall NumberCallerDraw(const void* dcaller, IplImage** dimage, int* dnum);
extern "C" __declspec(dllimport) void __stdcall NumberCallerSave(const void* dcaller, char* filename );
 
void __fastcall TNumberCaller::save( const String &filename )
{
    NumberCallerSave( TnumberCaller::oPointer, AnsiString(filename).c_str() );
}
 
void __fastcall TNumberCaller::draw( ArrayOfImage &dimages )
{
    DynamicArray<IplImage*> images;
    DynamicArray<int> nums;
 
    int count = dimages.Length;
    images.Length = count;
    nums.Length = count;
 
    for (int idx = 0; idx < count; ++idx)
    {
        images[idx] = dimages[idx].Image;
        nums[idx] = idx;
    }
 
    NumberCallerDraw( TnumberCaller::oPointer, (count > 0) ? &images[0] : NULL, (count > 0) ? &nums[0] : NULL );
}
 
...
 
ArrayOfImage fimages;
 
fimages.Length = sqliteQuery->RecordCount;
int ndex = 0;
 
while (!sqliteQuery->Eof)
{ 
    imagedrawn = new TBitmap;
    try
    {
        //codes here...
        fimages[ndex].Image = Bitmap2IplImage(imagedrawn);
        ++ndex;
    }
    __finally
    {
        delete imagedrawn;
    }
 
    xdbimage = new TBitmap;
    try
    {
        IplImage2Bitmap(fimages[ndex-1].Image, xdbimage);
        imgCallerLocation->Picture->Assign(xdbimage);
    }
    __finally
    {
        delete xdbimage;
    }
 
    sqliteQuery->Next();
}
 
...
 
TNumberCaller *tcallerid = new TNumberCaller;
try
{
    tcallerid->createNumberCaller(1,100.1);
    tcallerid->save(_y_filename_);
    tcallerid->draw(fimages);
    ...
}
__finally
{
    delete tcallerid;
}


That being said, how does NumberCallerDraw() in the DLL know how many items are being passed in the two arrays? The DLL code you showed does not allow for that. Clearly the array counts are dynamic, so more input parameters are needed so the DLL does not go out of bounds when accessing the arrays.

--
Remy Lebeau (TeamB)
roca robin

Posts: 140
Registered: 9/10/06
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 7, 2018 12:10 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
In fact, your C++Builder code shouldn't even compile, because the DLL's NumberCallerDraw() function only has 3 parameters, but you are trying to pass it 4 values in you C++Builder code.
No, sorry, This is the reason why it was 3 parameters than 4, but it's 2 only then 4 parameters carried away.

//..in my unumbercaller.H
//
class xCommon: TInterfacedObject
{
public:
friend class TNumberCaller;
TNumberCaller* XDATA;
void __fastcall Create( TNumberCaller* ydata );
};

class TNumberCaller: public xCommon {
public:
friend class xCommon;
void __fastcall createNumberCaller( int dial1 = 1, double dial2 = dbldial );
void __fastcall save( const String filename);
void __fastcall load( const String filename);
void __fastcall draw( ArrayOfImage dimage, ArrayOfInteger dnum );
__fastcall virtual ~TNumberCaller();
};

//..in my unumbercaller.CPP
//
void __fastcall xCommon::Create( TNumberCaller *ydata )
{
XDATA = ydata;
}

//..other codes here..

extern "C" __declspec(dllimport) void __stdcall NumberCallerDraw(const void* dcaller,
ArrayOfImage dimage, ArrayOfInteger dnum);

void __fastcall TNumberCaller::createNumberCaller( int dial1, double dial2 )
{
Create(Create_NumberCaller( dial1, dial2 )); //..xCommon WAS Here...
}

//..other codes here..

void __fastcall TNumberCaller::draw(ArrayOfImage dimage, ArrayOfInteger dnum )
{
NumberCallerDraw( /*TnumberCaller::oPointer*/ XDATA, dimage.Length, dimage, dnum ); //..xCommon WAS Here...
}

Now that's why I only called 3 params out of 4,

Your C++Builder code can use DynamicArray variables for purposes of memory management, but DO NOT declare parameters of imported DLL functions as being DynamicArray on the C++Builder side. For interop purposes, you need to use the same (or at least equivalent) declarations in both compilers.

and IF it's because of the Array declaration I had, then I will try your thoughts,

thank you, and message you back then..
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 7, 2018 9:04 AM   in response to: roca robin in response to: roca robin
roca robin wrote:

No, sorry, This is the reason why it was 3 parameters than 4, but
it's 2 only then 4 parameters carried away.

The DLL is still expecting only 3 parameters, but you are passing 4
values to it:

// 3 PARAMETERS!
extern "C" __declspec(dllimport) void __stdcall NumberCallerDraw(const
void* dcaller, ArrayOfImage dimage, ArrayOfInteger dnum);
 
...
 
// 4 PARAMETER VALUES!
NumberCallerDraw( /*TnumberCaller::oPointer*/ XDATA, dimage.Length,
dimage, dnum );


Spin it any way you want, this is still a mismatch that the compiler
should be complaining about.

--
Remy Lebeau (TeamB)
roca robin

Posts: 140
Registered: 9/10/06
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 7, 2018 12:43 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
OK, during Quick testing...

//..unumbercaller.H code...
struct TIplImage
{
IplImage *Image;
};
typedef DynamicArray< TIplImage > ArrayOfImage;
typedef DynamicArray< int > ArrayOfInteger;


//..WinForm codes..

ArrayOfImage fimages;

//..codes here..

fimages[ndex].Image = dbimage; //..First error, lack of .Image..now its fine, But
fnumbers[ndex] = ndex;

xdbimage = new TBitmap();
IplImage2Bitmap(fimages[ndex].Image, xdbimage); //..Second error, lack of .Image..now its fine, But
imgCallerLocation->Picture->Assign(xdbimage);

//..codes here..

ndex+=1;
sqliteQuery->Next();

Still I have the same PopUP Error Message

and I think this should be replaced, seeing through.....
void __fastcall TNumberCaller::draw( ArrayOfImage &dimages )
{
DynamicArray<IplImage*> images;
DynamicArray<int> nums;

int count = dimages.Length;
images.Length = count;
nums.Length = count;

for (int idx = 0; idx < count; ++idx)
{
images[idx] = dimages[idx].Image;
nums[idx] = idx;
}

NumberCallerDraw( TnumberCaller::oPointer, (count > 0) ? &images[0] : NULL, (count > 0) ? &nums[0] : NULL );
}

and so still debugging....

replaced that with this,
void __fastcall TNumberCaller::draw(ArrayOImage dimage, ArrayOfInteger dnum )
{

DynamicArray<IplImage*> images;

int count = dimage.Length;
images.Length = count;
dnum.Length = count;

for (int idx = 0; idx < count; ++idx)
{
images[idx] = dimage[idx].Image;
dnum[idx] = idx;
}

NumberCallerDraw( /*TnumberCaller::oPointer*/ XDATA, dnum[0], images, dnum ); //..Different Error Message says...trying to find out images....
}

So, I figure it out.... change
FROM:
extern "C" __declspec(dllimport) void __stdcall NumberCallerDraw(const void* dcaller,
ArrayOfImage dimage, ArrayOfInteger dnum);
TO:
extern "C" __declspec(dllimport) void __stdcall NumberCallerDraw(const void* dcaller,
DynamicArray<IplImage*> dimage, ArrayOfInteger dnum);

So, the same PopUp Error Message again

Additional thoughts, Used by Delphi with no problem at all, so I think I will leave this line of code structure is Ok.
//..Code from vc12 which make .DLL after buid! //..or a DLL wrapper

I_API void __stdcall NumberCallerDraw(TNumberCaller* dcaller, IplImage** dimage, int* dnum)
{
//
}

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 7, 2018 9:17 AM   in response to: roca robin in response to: roca robin
roca robin wrote:

//..unumbercaller.H code...
struct TIplImage
{
IplImage *Image;
};

Why did you remove the construct and destructor that I had in that
struct? They were there for a reason. Do you understand what RAII is?
If not, you need to learn it if you want to be proficient at C++.

ArrayOfImage fimages;

//..codes here..

fimages[ndex].Image = dbimage; //..First error, lack of .Image..now

Not true. fimages[ndex] returns a reference to a TIplImage object, and
Image is a public member of TIplImage.

its fine, But fnumbers[ndex] = ndex;

There is no fnumbers array in the second example that I gave you. You
are mixing together the two examples I gave you. They are not meant to
be mixed.

IplImage2Bitmap(fimages[ndex].Image, xdbimage); //..Second error,
lack of .Image..

Again, not true, for the same reason as above.

Still I have the same PopUP Error Message

Then you need to lean how you use your debugger better so you can track
down EXACTLY where the error is coming from and why it is being raised.

and I think this should be replaced, seeing through.....

replaced that with this,

No, it shouldn't. One, because you are passing in a useless parameter
(dnum) that the caller has no business passing in at all. Two, because
you should be passing arrays by reference, not by value. And three,
because of what I said earlier about you passing 4 parameters to a
function that only expects 3 parameters. Even if it did take 4
parameters, it doesn't make sense to pass 'dnum[0]' as a parameter
value, you probably meant to pass 'count' instead.

So, I figure it out.... change

FROM:

extern "C" __declspec(dllimport) void __stdcall
NumberCallerDraw(const void* dcaller, ArrayOfImage dimage,
ArrayOfInteger dnum);

TO:

extern "C" __declspec(dllimport) void __stdcall
NumberCallerDraw(const void* dcaller, DynamicArray<IplImage*> dimage,
ArrayOfInteger dnum);

NO, NO, NO! I already told you earlier, DO NOT declare the imported
DLL function with DynamicArray parameters. The CORRECT signature,
based on your original posting, is:

extern "C" __declspec(dllimport) void __stdcall NumberCallerDraw(const
void* dcaller, IplImage** dimage, int* dnum);


Leave it like that.

Used by Delphi with no problem at all

Then you are not translating it to C++ corrctly. What does the Delphi
code look like?

so I think I will leave this line of code structure is Ok.

No, it is not OK.

--
Remy Lebeau (TeamB)
roca robin

Posts: 140
Registered: 9/10/06
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 7, 2018 5:49 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
p.S:
I still got External Exception E06D7363
//////////////////////
THE C++BUILDER CODE
//////////////////////
//..unumbercaller.h
#include <System.hpp>
#include "opencv2/imgproc/imgproc_c.h"

struct TIplImage
{
IplImage *Image;
TIplImage() : Image(NULL) {}
~TIplImage() { cvReleaseImage(&Image); }
};

typedef DynamicArray< TIplImage > ArrayOfImage;
typedef DynamicArray< int > ArrayOfInteger;
typedef DynamicArray< String > ArrayOfString;

const double dbldial = 1000.1;

class xCommon: TInterfacedObject
{
public:
friend class TNumberCaller;
TNumberCaller* creator;
void __fastcall Create( TNumberCaller* xpointer );
};

//INTERFACE, NOT USABLE
/*
class
INumberCaller: public IUnknown
{
public:
virtual void __fastcall draw(ArrayOfImage &dimage) = 0;
virtual void __fastcall save(const String fn ) = 0;
virtual void __fastcall load(const String fn ) = 0;
};
*/

class TNumberCaller: public xCommon
{
public:
friend class xCommon;
void __fastcall createNumberCaller( int dial1 = 1, double dial2 = dbldial );
__fastcall virtual ~TNumberCaller();
void __fastcall draw(ArrayOfImage &dimage);
void __fastcall save(const String fn );
void __fastcall load(const String fn );
};

//
//
//
//
//

//..unumbercaller.cpp
#include <vcl.h>
#pragma hdrstop
#include <System.hpp>
#include "unumbercaller.h"

void __fastcall xCommon::Create( TNumberCaller *xpointer )
{
creator = xpointer;
}

extern "C" __declspec(dllimport) TNumberCaller* __stdcall Create_NumberCaller( int dial1 = 1, double dial2 = dbldial );
extern "C" __declspec(dllimport) void __stdcall NumberCallerDraw( const void* dcaller, IplImage** dimage, int* dnum );
extern "C" __declspec(dllimport) void __stdcall NumberCallerLoad(const void* dcaller, char* fn);
extern "C" __declspec(dllimport) void __stdcall NumberCallerSave(const void* dcaller, char* fn);
extern "C" __declspec(dllimport) void __stdcall DestroyNumberCaller(const void* x);

/* TNumberCaller */
void __fastcall TNumberCaller::createNumberCaller( int dial1, double dial2 )
{
Create(Create_NumberCaller( dial1, dial2 ));
}

__fastcall TNumberCaller::~TNumberCaller( )
{
if (( creator != NULL ) )
{
DestroyNumberCaller( creator );
creator = NULL;
}
}

void __fastcall TNumberCaller::draw(ArrayOfImage &dimage)
{
DynamicArray<IplImage*> images;
DynamicArray<int> nums;
int count = dimage.Length;
images.Length = count;
nums.Length = count;
for (int idx = 0; idx < count; ++idx)
{
images[idx] = dimage[idx].Image;
nums[idx] = idx;
}

//=============================================================================
//
//STILL I GOT DIVISION BY ZERO / External Exception E06D7363 by this line below
//
NumberCallerDraw( creator, (count > 0) ? &images[0] : NULL, (count > 0) ? &nums[0] : NULL );
}

void __fastcall TNumberCaller::load(const String fn )
{
NumberCallerLoad( creator, ( PAnsiChar ) ( &( ((AnsiString) fn )[1] ) ) );
}

void __fastcall TNumberCaller::save(const String fn )
{
NumberCallerSave( creator, ((AnsiString) fn ).c_str());
}

.
.
.
.
.
.
.
.

//////////////////////
THE DELPHI CODE
//////////////////////
///********************************************
///********************************************
//
unit unumbercaller;

interface

Uses ocv.core.types_c{,inputoutputcall};

const
dbldial = 1000.1;
mycppdialdll = 'mycppdialdll.dll';

type
ArrayOfImage = Array of pIplImage;
ArrayOfInteger = Array of integer;
xCommon = class(TInterfacedObject)
protected
creator: Pointer;
public
constructor Create(const xpointer: Pointer);
end;

INumberCaller = interface
procedure save(const fn: string);
procedure load(const fn: string);
procedure draw(dimage: ArrayOfImage; dnum: ArrayOfInteger);
end;

TNumberCaller = class(xCommon, INumberCaller)
public
constructor createNumberCaller(dial1: Integer = 0; dial2: double = dbldial);
procedure draw(dimage: ArrayOfImage; dnum: ArrayOfInteger);
procedure load(const fn: string);
procedure save(const fn: string);

destructor Destroy; override;
end;

implementation

constructor xCommon.Create(const xpointer: Pointer);
begin
creator := xpointer;
end;

function Create_NumberCaller(dial1: Integer = 1; dial2: double = dbldial): Pointer; stdcall;
external mycppdialdll name '_Create_NumberCaller@12';

procedure NumberCallerDraw(const x: Pointer; dimage: Pointer; dnum: Pointer); stdcall;
external mycppdialdll name '_NumberCallerDraw@16';

procedure NumberCallerLoad(const x: Pointer; fn: PAnsiChar); stdcall;
external mycppdialdll name '_NumberCallerLoad@8';

procedure NumberCallerSave(const x: Pointer; fn: PAnsiChar); stdcall;
external mycppdialdll name '_NumberCallerSave@8';

procedure DestroyNumberCaller(const x: Pointer); stdcall;
external mycppdialdll name '_DestroyNumberCaller@4';
{ TNumberCaller }
constructor TNumberCaller.createNumberCaller(dial1:integer; dial2:double);
begin
inherited Create(Create_NumberCaller(dial1, dial2));
end;

procedure TNumberCaller.draw(dimage: ArrayOfImage; dnum: ArrayOfInteger);
begin
NumberCallerDraw(creator, @dimage[0], @dnum[0]);
end;

procedure TNumberCaller.load(const fn: string);
begin
NumberCallerLoad(creator, pAnsiChar(AnsiString(fn)));
end;

procedure TNumberCaller.save(const fn: string);
begin
NumberCallerSave(creator, pAnsiChar(AnsiString(fn)));
end;

destructor TNumberCaller.Destroy;
begin
if Assigned(creator) then
begin
DestroyNumberCaller(creator);
creator := nil;
end;
inherited;
end;

end.


///********************************************
///THE main Delphi code :: which RUNS very good!
///
unit Unit1;

interface

uses
unumbercaller,
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
callerid : INumberCaller; // I_Number_Caller

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
fimages:ArrayofImage;
fnumbers:ArrayofInteger;
begin
//
callerid := TNumberCaller.createNumberCaller(1,101.1);
//
//
callerid.load('testload');
//
callerid.save('testsave');
//
callerid.draw(fimages, fnumbers);
//
//
end;

end.

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero? [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 7, 2018 8:47 PM   in response to: roca robin in response to: roca robin
roca robin wrote:

p.S:
I still got External Exception E06D7363

You are declaring the DLL's NumberCallerDraw() function incorrectly in both Delphi and C++.

When the Delphi code imports NumberCallerDraw() from the DLL, it is being imported as '_NumberCallerDraw@16'. The @16 means there are 16 bytes used for parameters on the call stack. But the parameters you have specified only account for 12 bytes (sizeof(Pointer) = 4, so 3 * 4 = 12). There is clearly a 4-byte parameter missing in your declarations (an integer for the numbr of elements in the arrays, perhaps?).

So, your claim that the Delphi code "RUNS very good" can't possibly be true, because it doesn't call NumberCallerDraw() correctly. I pointed this out to you earlier.

In any case, your translation of the Delphi code to C++ is not even close to being correct. Try something more like this instead:

unumbercaller.h

#ifndef unumbercallerH
#define unumbercallerH
 
#include <System.hpp>
#include "opencv2/imgproc/imgproc_c.h"
 
static const double dbldial = 1000.1;
static const String mycppdialdll = _D("mycppdialdll.dll");
 
typedef DynamicArray<IplImage*> ArrayOfImage;
typedef DynamicArray<int> ArrayOfInteger;
 
class xCommon : public TInterfacedObject
{
protected:
    void *creator;
public:
    __fastcall xCommon(void *xpointer);
};
 
__interface INumberCaller : public IInterface
{
public:
    virtual void __fastcall save(const String fn) = 0;
    virtual void __fastcall load(const String fn) = 0;
    virtual void __fastcall draw(ArrayOfImage dimage, ArrayOfInteger dnum) = 0;
};
 
class TNumberCaller : public xCommon, public INumberCaller
{
    INTFOBJECT_IMPL_IUNKNOWN(xCommon);
public:
    __fastcall TNumberCaller(int dial1 = 0, double dial2 = dbldial);
    __fastcall ~TNumberCaller();
 
    void __fastcall draw(ArrayOfImage dimage, ArrayOfInteger dnum);
    void __fastcall load(const String fn);
    void __fastcall save(const String fn);
};
 
#endif


unumbercaller.cpp

#include <vcl.h>
#pragma hdrstop
 
#include "unumbercaller.h"
 
__fastcall xCommon::xCommon(void *xpointer)
    : creator(xpointer)
{
}
 
extern "C"
{
    // also add the import .lib for mycppdial.dll to your project...
    __declspec(dllimport) void* __stdcall Create_NumberCaller(int dial1 = 1, double dial2 = dbldial);
    __declspec(dllimport) void __stdcall NumberCallerDraw(const void *x, int count, void *dimage, void *dnum);
    __declspec(dllimport) void __stdcall NumberCallerLoad(const void *x, const char *fn);
    __declspec(dllimport) void __stdcall NumberCallerSave(const void *x, const char *fn);
    __declspec(dllimport) void __stdcall DestroyNumberCaller(const void *x);
}
 
/* TNumberCaller */
 
__fastcall TNumberCaller::TNumberCaller(int dial1, double dial2)
    : xCommon(Create_NumberCaller(dial1, dial2))
{
}
 
__fastcall TNumberCaller::~TNumberCaller()
{
    if (creator)
    {
        DestroyNumberCaller(creator);
        creator = NULL;
    }
}
 
void __fastcall TNumberCaller::draw(ArrayOfImage dimage, ArrayOfInteger dnum)
{
    NumberCallerDraw(creator, dimage.Length, &dimage[0], &dnum[0]);
}
 
void __fastcall TNumberCaller::load(const String fn)
{
    NumberCallerLoad(creator, AnsiString(fn).c_str());
}
 
void __fastcall TNumberCaller::save(const String fn)
{
    NumberCallerSave(creator, AnsiString(fn).c_str());
}


Unit1.h

#ifndef Unit1H
#define Unit1H
 
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
 
#inclue "unumbercaller.h"
 
class TForm1 : public TForm
{
__published:	// IDE-managed Components
private:	// User declarations
public:		// User declarations
    __fastcall TForm1(TComponent *Owner);
}
 
extern PACKAGE TForm1 *Form1;
extern DelphiInterface<INumberCaller> callerid; // I_Number_Caller
 
#endif


Unit1.cpp

#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.hpp"
 
#pragma package(smart_init)
#pragma resource "*.dfm"
 
TForm1 *Form1;
DelphiInterface<INumberCaller> callerid;
 
__fastcall TForm1::TForm1(TComponent *Owner)
    : TForm(Owner)
{
    callerid = (INumberCaller*) new TNumberCaller(1, 101.1);
    callerid->load(_D("callerfilenamebackup1.xlsx"));
    callerid->save(_D("callerfilenamebackup2.xlsx"));
    callerid->draw(fimages, fnumbers); // <-- where are those objects?
}


--
Remy Lebeau (TeamB)
roca robin

Posts: 140
Registered: 9/10/06
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero? [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 7, 2018 10:52 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
your claim that the Delphi code "RUNS very good" can't possibly be true
Ok, I understand, that was a typo, I change number for testing purposes and I had not change that since my last copy paste.
But truly it runs on Delphi, that's why it's my basis to convert to c++ builder.

<-- where are those objects?
fimages and fnumbers are objects from the sql database that reads image location and phone numbers


This line doesn't work with me even I rename it to Create
__fastcall TNumberCaller::TNumberCaller(int dial1, double dial2)
: xCommon(Create_NumberCaller(dial1, dial2)) //This line doesn't work with me even I rename it to Create
{
}

What if I have to create another Number Caller for example Create_NumberCaller2 with different parameter ?
eq.,
createNumberCaller1(1,100.1);
createNumberCaller2(1, 100.1, "Mansion Street, California", 1100);

?

I think these does not apply if I have options to use any create number,

callerid = (INumberCaller*) new TNumberCaller(1, 101.1);

can you please change the lines of code for better usage?
like kind of these,
callerid = (INumberCaller*) new TNumberCalle->createNumberCaller2(1, 100.1, "Mansion Street, California", 1100); or something will work
callerid->load(_D("callerfilenamebackup1.xlsx"));

thank you Remy,
nice to read your comments.

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero? [Edit] [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 8, 2018 9:49 AM   in response to: roca robin in response to: roca robin
roca robin wrote:

<-- where are those objects?
fimages and fnumbers are objects from the sql database that reads
image location and phone numbers

That is not what I meant. Where are the fimages and fnumbers variables
declared, and how are they populated? You didn't show that code.

This line doesn't work with me even I rename it to Create

There were a couple of typos in my last example. I have corrected
them, and tested the code to make sure it works now.

FYI, constructors in C++ MUST have the same name as the class, they
can't have user-defined names, like in Delphi. So it wonn't work if
you rename the constructor to Create().

What if I have to create another Number Caller for example
Create_NumberCaller2 with different parameter ?

Simply write another class and add the extra parameters you want. What
is so hard about that?

__interface INumberCaller2 : public INumberCaller
{
    // more methods here...
};
 
class TNumberCaller2 : public xCommon, public INumberCaller2
{
    INTFOBJECT_IMPL_IUNKNOWN(xCommon);
public:
    __fastcall TNumberCaller2(int dial1 = 0, double dial2 = dbldial,
const String &address3 = "", int param4 = 0);
    __fastcall ~TNumberCaller2();
 
    // INumberCaller methods...
    void __fastcall draw(ArrayOfImage dimage, ArrayOfInteger dnum);
    void __fastcall load(const String fn);
    void __fastcall save(const String fn);
 
    // INumberCaller2 methods...
    ...
};
 
__fastcall TNumberCaller2::TNumberCaller2(int dial1, double dial2,
const String &address3, int param4)
    : xCommon(Create_NumberCaller2(dial1, dial2,
AnsiString(address).c_str(), param4))
{
}
 
DelphiInterface<INumberCaller2> callerid2;
callerid2 = (INumberCaller2*) new TNumberCaller2(1, 101.1, "Mansion
Street, California", 1100);


--
Remy Lebeau (TeamB)
roca robin

Posts: 140
Registered: 9/10/06
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero? [Edit] [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 8, 2018 11:29 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
You didn't show that code.
//---------------------------------------------------------------------------
void __fastcall TForm1::LoadDatabase()
{
//int ndex;
IplImage *dbimage;
int id;
String owner;
Variant vimage;
TBitmap *imagedrawn;
TBitmap *xdbimage;

ArrayOfImage fimages;
ArrayOfInteger fnumbers;
ArrayOfString fowners;

size = cvSize(640, 480);

if (sqliteconnect()) {
//
//sql codes here...
//
sqliteQuery->Open();
ndex = sqliteQuery->RecordCount;
sqliteQuery->First();
if (sqliteQuery->Eof){
ndex=0;
return;
}

fowners.set_length(ndex);
fimages.Length = ndex;
fnumbers.Length = ndex;

ndex=0;

while (!sqliteQuery->Eof){
//..Test Fields Only
id=sqliteQuery->FieldByName("id")->AsInteger;
owner=sqliteQuery->FieldByName("owner")->AsString;
vimage=sqliteQuery->FieldByName("location")->AsVariant;

imagedrawn = new TBitmap();
VariantToBMPViaJPEG(&vimage, imagedrawn);

fimages[ndex] = Bitmap2IplImage(imagedrawn);
fnumbers[ndex] = ndex;
fowners[ndex] = owner;

//..For Testing Only
xdbimage = new TBitmap();
IplImage2Bitmap(fimages[ndex], xdbimage);
imgCallerLocation->Picture->Assign(xdbimage);

ndex+=1;
sqliteQuery->Next();
}
xdbimage->Free();
imagedrawn->Free();
sqliteQuery->Close();

//icallerid = (INumberCaller*) new TNumberCaller();

}
}
//---------------------------------------------------------------------------


__fastcall TNumberCaller2::TNumberCaller2(int dial1, double dial2,
const String &address3, int param4)
: xCommon(Create_NumberCaller2(dial1, dial2,
AnsiString(address).c_str(), param4))
{
}

it says.... and same as TNumberCaller1

xCommon' is not an unambiguous base class of 'xCommon
Am I missing something?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero? [Edit] [Edit] [Edit]
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 8, 2018 1:25 PM   in response to: roca robin in response to: roca robin
roca robin wrote:

void __fastcall TForm1::LoadDatabase()

That code has several memory leaks in it. You are leaking imagedrawn
and xdbimage on every loop iteration, and then after the loop finishes,
you free (incorrectly) only the 2 TBitmap objects that were created on
the last loop iteration.

You are also not protecting the code from exceptions.

Try this instead:

void __fastcall TForm1::LoadDatabase()
{
    int ndex;
    IplImage *dbimage;
    int id;
    String owner;
    Variant vimage;
    TBitmap *imagedrawn;
    TBitmap *xdbimage;
 
    ArrayOfImage fimages;
    ArrayOfInteger fnumbers;
    ArrayOfString fowners;
 
    size = cvSize(640, 480);
 
    if (sqliteconnect())
    {
        //
        //sql codes here...
        //
        sqliteQuery->Open();
        try
        {
            sqliteQuery->First();
            if (sqliteQuery->Eof)
                return;
 
            ndex = sqliteQuery->RecordCount;
 
            fowners.Length = ndex;
            fimages.Length = ndex;
            fnumbers.Length = ndex;
 
            ndex = 0;
 
            do
            {
                //..Test Fields Only
                id = sqliteQuery->FieldByName("id")->AsInteger;
                owner = sqliteQuery->FieldByName("owner")->AsString;
                vimage =
sqliteQuery->FieldByName("location")->AsVariant;
 
                imagedrawn = new TBitmap;
                try
                {
                    VariantToBMPViaJPEG(&vimage, imagedrawn);
 
                    fimages[ndex] = Bitmap2IplImage(imagedrawn);
                    fnumbers[ndex] = ndex;
                    fowners[ndex] = owner;
 
                    ++ndex;
                }
                __finally
                {
                    delete imagedrawn;
                }
 
                //..For Testing Only
                xdbimage = new TBitmap;
                try
                {
                    IplImage2Bitmap(fimages[ndex-1], xdbimage);
                    imgCallerLocation->Picture->Assign(xdbimage);
                }
                __finally
                {
                    delete xdbimage;
                }
 
                sqliteQuery->Next();
            }
            while (!sqliteQuery->Eof);
        }
        __finally
        {
            sqliteQuery->Close();
        }
    }
}


__fastcall TNumberCaller2::TNumberCaller2(int dial1, double dial2,
const String &address3, int param4)
: xCommon(Create_NumberCaller2(dial1, dial2,
AnsiString(address).c_str(), param4))
{
}

it says.... and same as TNumberCaller1
xCommon' is not an unambiguous base class of 'xCommon
Am I missing something?

Then you did somthing wwrong in the declarations of TNumberCaller1 and
TNumberCaller2, because the TNumberCaller2 I showed you derives from
xCommon, so it is not an unambiguous base class.

--
Remy Lebeau (TeamB)
roca robin

Posts: 140
Registered: 9/10/06
Re: What is meant of double asterisk, ArrayOf? I get Division by Zero? [Edit] [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 10, 2018 9:20 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
IT WAS SO PAINFUL arriving to a solution, that.....

It's was only the Size of the saved Image loading it to different size, and the ndex Number.

size saved in the database was 1280x1024 and the size which to load is 640x480 , lol
and ndex which is the next issue why it continues to have the same Error PopUp message....

Both of them causes the Division by Zero...

@Rem
thank you so much,

whowwww...time..... what a bummer.... I almost surrender from c++ builder, lol
============================(((((())))))===============================================
========================THANK=()=YOU=============================================
============================(((((())))))===============================================

@Rem...

p.S
I get back to ArrayOfImage.

extern "C" __declspec(dllimport) void __stdcall NumberCallerDraw(const void* dcaller, ArrayOfImage dimage, ArrayOfInteger dnum);

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02