Thanks for any help
Gerald
Nick
The best approach would be to have the EXE allocate the memory for the
array and pass the array as a Var parameter to the DLL for filling.
This way it is clear who owns the memory for the array and is responsible
for cleaning it up if required. The details depend on information you have
not given. E.g. do you know the size of the array at compile-time? Is the
DLL written in the same language as the executable? If not, which is the
Delphi side? What language is used for the other side?
Peter Below (TeamB) 10011...@compuserve.com)
No replies in private e-mail, please, unless explicitly requested!
Thanks for the response.
What you suggested is actually what I am working on doing. The array
structure memory is allocated in the calling program (written using D3) and
passed to the DLL function (also written using D3).
The DLL function is declared as follows:
function RdTopupLog(Address : byte; var Topups : array of TTopupLog) :
word;
begin
.....
end;
In the main code, the array is declared as follows in the private section
of the object
TopupLog : Array[0..50] of TTopupLog;
feeder : byte;
and called as follows:
RdTopupLog(feeder, TopupLog);
Everything works fine when both functions are in the same project, but when
the DLL function is called while in the DLL, I get an access violation.
Am I doing something wrong?
Thanks
Gerald
Peter Below (TeamB) <10011...@compuXXserve.com> wrote in message ...
As it turned out, I had a function name which duplicated some Windows API
function (ReadEventLog). It caused problems. Renaming the function
resolved the problem.
Thanks for the help.
Gerald
Is this combination possible using the method you suggest? And how would I
allocate the memory?
Sarah
A C struct is basically the same as a Delphi record. You have to deal with
field alignment issues (need to know which #pragma align value the C compiler uses
by default, Delphi by default aligns fields in a record that has not been declared
with the packed keyword for optimal access, which depends on field size. See
Object Pascal Language Guide) and properly translate the field types used in C to
Delphi types (which means: no String fields! char fieldname[n] is fieldname: Array
[0..n-1] of Char in Delphi).
In C an array of structures parameter is usually declared in the form
structtype paramname[]
or
structtype* paramname
Both are in fact different notations for the same thing: a pointer to the array,
which is the same as a pointer to the arrays first element. So a possible
translation to Delphi, which avoids using pointers, is
Var paramname: TStructtype;
to which you then pass the *first* element of the array. Since this is a Var
parameter it results in passing the address of the first element, just what the C
side requires.
Since you do not know the number of array elements up front you have to allocate
memory for them at run-time, dynamically. Using a D4 dynamic array for this should
in principle work, e.g. you do a
Var
params: Array of TStructtype;
Begin
SetLength( params, numberofelementsneeded );
...init elements
DllFunction( params[0], numberofelementsneeded );
Note that the DLL function is handed the actual number of elements. If your DLL
interface does not allow for that it is probably seriously flawed, since the
DLLfunction has no way to determine how many entries the array you fed it has,
unless there is some convention to place a special marker record as last in the
array, for instance.
If you don't work with D4 you have to fall back to a pointer-to-array approach,
e.g.
Type
TStructArray = Array [0..High(Cardinal) div Sizeof( TStructtype )-1] of
TStructtype;
PStructArray = ^TStructArray;
Var
pParams: PStructArray;
Begin
pParams := AllocMem( numberofelementsneeded * Sizeof( TStructtype ));
try
...init pParams^[0] to pParams^[numberofelementsneeded-1]
DLLFunction( pParams^[0], numberofelementsneeded );
finally
FreeMem( pParams );
end;