Using a Pointer types vs using VAR in a parameter list of an exported function

29 views
Skip to first unread message

Michael Wittig

unread,
Dec 14, 2001, 1:09:15 PM12/14/01
to
Hi All,

First, I'm new to Delphi and this list (2 weeks now) and am very thankful
for
the insights and suggestions given to me by members of this list. Thanks
again :-).

A new question, but context first.

I have an application and DLL's written in C++ that are loading and calling
functions located in DLL's written in Delphi. The C++ code is calling
functions
and passing pointers to a variety of different data types such as null
terminated
strings, structures and the like.

Lets say for example that I have the following structure in C++:

struct A
{
int a;
double b;
char c[80];
};

A a = { 1; 2.0 ; ""};


And I call the the following function located in a DLL written in Delphi:

int result = DelphiDLLFunc( &a )


On the Delphi side I have:


type
A = record
a: integer;
b: double;
c: Pchar;
end;


function DelphiDLLFunc( var p_A: A );

Is the use of the var (pass by reference) correct here? It seems to work
and by all counts, p_A is a pointer
by virtue of the 'var'. Correct?

Or does one call p_A a reference to A rather than a pointer? In C++ you
can have both references and pointers,
the difference as you know, is in the notation required to dereference. In
the case of a pointer you use the '->' notation
and in the case of a reference you use the standard ' dot ' notation.

SOOoo.....
Is p_A strictly a reference (in Delphi) for which I use the dot notation to
access members ie: p_A.a etc.... (This seems to work)
OR
Is p_A strictly a pointer for which I can use the suffixed '^' notation to
access members. ie: p_A^a etc.....(Haven't tried this yet)

Or, would it be more correct to use a pointer:
ie: type
PointerToA : ^A;
and
function DelphiDLLFunc( PointerToA );

OR are both methods equally correct?

Also, is my use of a Pchar to receive the char c[80] member correct?


Any knowledgeable and experienced help would be much appreciated.

Thanks again.


Rudy Velthuis (TeamB)

unread,
Dec 14, 2001, 2:25:59 PM12/14/01
to
In article <3c1a3a7b$1_2@dnews>, Michael Wittig says...


#pragma pack(push, 1) // to align with packed!

> struct A
> {
> int a;
> double b;
> char c[80];
> };
>
> A a = { 1; 2.0 ; ""};
>
> And I call the the following function located in a DLL written in Delphi:
>
> int result = DelphiDLLFunc( &a )

if your C prototype is:

extern "C" int __declspec(dllimport) __stdcall DelphiDLLFunc(A* a);

or, if you dislike __stdcall:

extern "C" int __declspec(dllimport) DelphiDLLFunc(A* a);

>
>
> On the Delphi side I have:
>
>
> type

TA = packed record // #pragma pack(push, 1) in C

> a: integer;
> b: double;

c: array[0..79] of Char;

> end;

PChar is nothing more than a char* in C (a pointer, but with some extra
semantics). Since you have an array in your C struct, you must have one
in your Delphi record too.

Given my prototypes above, your Delphi prototype should look like this:

function DelphiDLLFunc(var A: TA): Integer; stdcall;

Or, if you dislike stdcall:

function DelphiDLLFunc(var A: TA): Integer; cdecl;

You could generate a header for the Delphi code by compiling it with the
command line compiler, and using -JPHNE as one of the command line
options. This will make the compiler generate a .hpp header, which
contains the correct prototypes for your Delphi functions and types.

> Is the use of the var (pass by reference) correct here? It seems to work
> and by all counts, p_A is a pointer
> by virtue of the 'var'. Correct?

Correct.



> Or does one call p_A a reference to A rather than a pointer? In C++ you
> can have both references and pointers,

Functionally, and internally, they are the same. Only semantically, and
syntactically, they are different.

> SOOoo.....
> Is p_A strictly a reference (in Delphi) for which I use the dot notation to
> access members ie: p_A.a etc.... (This seems to work)

You actually ought to use the ^. notation, but in cases where . alone is
not ambiguous, you can do without the ^ .

BTW, in Delphi it is custom to start type names with a T, and pointers
to such type with a P:

type
PMyRec = ^TMyRec;
TMyRec = record
...
end;
--
Rudy Velthuis (TeamB)

Peter Below (TeamB)

unread,
Dec 14, 2001, 3:30:58 PM12/14/01
to
In article <3c1a3a7b$1_2@dnews>, Michael Wittig wrote:
> I have an application and DLL's written in C++ that are loading and calling
> functions located in DLL's written in Delphi. The C++ code is calling
> functions and passing pointers to a variety of different data types such
> as null terminated strings, structures and the like.
>
> struct A
> {
> int a;
> double b;
> char c[80];
> };
>
> int result = DelphiDLLFunc( &a )
> On the Delphi side I have:
> type
> A = record
> a: integer;
> b: double;
c: Pchar; <= wrong, should be array [0..79] of Char;

> end;
>
>
> function DelphiDLLFunc( var p_A: A );
>
> Is the use of the var (pass by reference) correct here?

Yes, a Var parameter in Delphi effectively passes a pointer to the variable
on call, so is equivalent to a pointer parameter in C. The only difference
is that you cannot (easily) pass Nil to a Var parameter, and the function
taking the parameter would have a hard time detecting the fact that it was
handed a Nil pointer. So if you need to interface to code that may pass or
expect a Nil value, do not use Var but use a pointer type, if Nil is not
to be expected, use Var.


Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitly requested!
Note: I'm unable to visit the newsgroups every day at the moment,
so be patient if you don't get a reply immediately.

Reply all
Reply to author
Forward
0 new messages