Discussion:
Calling a C++ Form from a Delphi Form
(too old to reply)
Chris Bruner
2008-08-06 19:03:45 UTC
Permalink
I'm getting lost in my classes and need to simplify. The biggest
simplification would be to remove delphi and just use C++, but I want to
do this a step (form) at a time.

My idea is to use dynamic creation of forms and call from the Delphi form.


That is, where the form would be dynamically created in Delphi

(for example).

function frmIFCAOptions : TfrmIFCAOptions;
begin
if (FfrmIFCAOptions = nil) then
Application.CreateForm(TfrmIFCAOptions,FfrmIFCAOptions);
if (FfrmIFCAOptions = nil) then
NoResourcesException;

Result := FfrmIFCAOptions;
end;

This function will create the form if needed and return the form once
created. (This tecnique can save a ton of memory for seldom used forms).


How would I do this with CBuilder forms, where I would create a Cbuilder
form as needed.

I was thinking of something like this, but the linker can't seem to find it.


class TForm1 : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
TForm *GetTForm1() { if (Form1==0) Form1 = new TForm1(Form1);
return Form1;
}
Remy Lebeau (TeamB)
2008-08-06 19:20:29 UTC
Permalink
Post by Chris Bruner
How would I do this with CBuilder forms, where I would create a Cbuilder
form as needed.
The same way you do in Delphi, ie:

TfrmIFCAOptions* frmIFCAOptions()
{
if (FfrmIFCAOptions == NULL)
Application->CreateForm(__classid(TfrmIFCAOptions),
&FfrmIFCAOptions);
// or:
// FfrmIFCAOptions = new TfrmIFCAOptions(Application);

if (FfrmIFCAOptions == NULL)
NoResourcesException();

return FfrmIFCAOptions;
}
Post by Chris Bruner
I was thinking of something like this, but the linker can't seem to find it.
What is the exact linker error? You need to be more specific.
Post by Chris Bruner
TForm *GetTForm1() { if (Form1==0) Form1 = new TForm1(Form1);
return Form1;
You are passing the NULLified Form1 pointer as the Owner of the TForm1
instance you are trying to create for the Form1 pointer. If you don't want
the new form to have an Owner, then specify NULL explicitally instead:

TForm *GetTForm1()
{
if (Form1==NULL)
Form1 = new TForm1(NULL);
return Form1;
}

Now, with that said - I would suggest moving the body of GetTForm() into the
form's .cpp file instead of having it inlined in the header file:

--- Unit1.h ---

class TForm1 : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------



--- Unit1.cpp ---

#include "Unit1.h"

TForm1 *Form1 = NULL;

TForm *GetTForm1()
{
if (Form1 == NULL)
Form1 = new TForm1(Application);
return Form1;
}


Gambit
Chris Bruner
2008-08-06 19:46:37 UTC
Permalink
Remy Lebeau (TeamB) wrote:
Thanks for the quick response.
Post by Remy Lebeau (TeamB)
What is the exact linker error? You need to be more specific.
I needed extern "C" for the delphi side to see it. (solved).
Post by Remy Lebeau (TeamB)
Post by Chris Bruner
TForm *GetTForm1() { if (Form1==0) Form1 = new TForm1(Form1);
return Form1;
I read that Delphi has everything by reference so it's changed to:
TForm & WINAPI _export GetTForm1() {

if (Form1==0) Application->CreateForm(__classid(TForm1), &Form1);
return *Form1;
}
}
Post by Remy Lebeau (TeamB)
You are passing the NULLified Form1 pointer as the Owner of the TForm1
instance you are trying to create for the Form1 pointer. If you don't want
TForm *GetTForm1()
{
if (Form1==NULL)
Form1 = new TForm1(NULL);
return Form1;
}
Not the intent in this case, once the form is created it shouldn't go
away so it's owner should be the application. However this is good to
know anyways.
Post by Remy Lebeau (TeamB)
Now, with that said - I would suggest moving the body of GetTForm() into the
OK, done.

new code is (inside unit1.cpp)

extern "C" {

TForm & WINAPI _export GetTForm1() {

if (Form1==0) Application->CreateForm(__classid(TForm1), &Form1);
return *Form1;
}
}


Thanks for your help!
Remy Lebeau (TeamB)
2008-08-06 19:53:45 UTC
Permalink
Post by Chris Bruner
I read that Delphi has everything by reference
Then you read wrong.
change it back to use pointers as before. That is what Delphi is actually
expecting.


Gambit
Chris Bruner
2008-08-06 20:26:49 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Chris Bruner
I read that Delphi has everything by reference
Then you read wrong.
change it back to use pointers as before. That is what Delphi is actually
expecting.
Gambit
From Delphi:
function GetIfcaRiaForm(): TForm; stdcall far; external 'dll123.dll';

called using:

GetIfcaRiaForm.ShowModal;


From C++:

extern "C" {

TForm & WINAPI _export GetIfcaRiaForm() {

if (IfcaRiaForm==0)
Application->CreateForm(__classid(TIfcaRiaForm), &IfcaRiaForm);
return *IfcaRiaForm;
}

}


Seems to work.
Remy Lebeau (TeamB)
2008-08-06 21:54:24 UTC
Permalink
Post by Chris Bruner
function GetIfcaRiaForm(): TForm; stdcall far; external 'dll123.dll';
That is using a pointer, not a reference. Object variables in Delphi are
pointers. The equivilent to that declaration in C++ is this:

TForm* __stdcall GetIfcaRiaForm();
Post by Chris Bruner
GetIfcaRiaForm.ShowModal;
Which would be this in C++:

GetIfcaRiaForm()->ShowModal();
Post by Chris Bruner
TForm & WINAPI _export GetIfcaRiaForm() {
That is wrong. This is what you need:

extern "C"
{
TForm* WINAPI _export GetIfcaRiaForm()
{
if( IfcaRiaForm == NULL )
Application->CreateForm(__classid(TIfcaRiaForm),
&IfcaRiaForm);
return IfcaRiaForm;
}
}
Post by Chris Bruner
Seems to work.
But is wrong.


Gambit

Loading...