wuwuxin 28 Posted April 25, 2021 (edited) I have a C DLL function, void FillArray(int* data, int num_element); from Delphi side, is the following caller code correct? var data: TArray<Integer>; SetLength(data, 100); FillArray(data, 100); Also, what would be the correct Delphi translation of the C function? Is the following correct? Should I use "const" or not? procedure FillArray(const data: TArray<Integer>; num_element: Integer); Edited April 25, 2021 by wuwuxin Share this post Link to post
David Heffernan 2345 Posted April 25, 2021 (edited) You need to specify the calling convention, probably cdecl. And I'd declare it as PInteger and pass Pointer(data). Edited April 25, 2021 by David Heffernan Share this post Link to post
Guest Posted April 25, 2021 1 hour ago, wuwuxin said: FillArray(data, 100); Should be FillArray(data, 100 * SizeOf(Integer)); And you can use const or var with the same result in this case, As David pointed to declare the function with PInteger and pass it by PInteger(@data[0]). Share this post Link to post
David Heffernan 2345 Posted April 25, 2021 1 hour ago, Kas Ob. said: As David pointed to declare the function with PInteger and pass it by PInteger(@data[0]). The reason I prefer Pointer(data) is that it doesn't trigger range check error if the array has length 0. 1 Share this post Link to post
wuwuxin 28 Posted April 25, 2021 Thank you very much for the advice. 1 minute ago, David Heffernan said: The reason I prefer Pointer(data) is that it doesn't trigger range check error if the array has length 0. Share this post Link to post
Guest Posted April 25, 2021 8 minutes ago, David Heffernan said: The reason I prefer Pointer(data) is that it doesn't trigger range check error if the array has length 0. You are totally right there, but i prefer sometimes to trigger it explicitly (in development) to make sure (in similar case to this as with an external API) that the called function is well equipped to handle such case, in other words to make sure i am not leaving it unhandled and unchecked, just as safe measure. Share this post Link to post
David Heffernan 2345 Posted April 25, 2021 1 hour ago, Kas Ob. said: You are totally right there, but i prefer sometimes to trigger it explicitly (in development) to make sure (in similar case to this as with an external API) that the called function is well equipped to handle such case, in other words to make sure i am not leaving it unhandled and unchecked, just as safe measure. Your way makes it impossible to pass an empty array. If an empty array is never valid, then fine. If an empty array is supported then the Pointer cast is preferable. Share this post Link to post
Guest Posted April 25, 2021 33 minutes ago, David Heffernan said: Your way makes it impossible to pass an empty array. If an empty array is never valid, then fine. If an empty array is supported then the Pointer cast is preferable. Right, but i am talking about this case in general, see, it is very rare to design your own code where you need to pass TArray (or any other defined indexed type) to a function with "pointer to array" with element length, most likely the destination belongs to another realm or simply put belongs to a code by different coder (or library), and on same side in cases other than the above example where length established locally, the length might be 0, in this case i prefer to have a nice overflow exception instead of unpredicted behaviour in case i missed explicitly a check against 0 length. It is just personal point of view, in many cases i prefer the compiler checks, unless performance is priority to consider. Share this post Link to post
Remy Lebeau 1394 Posted April 26, 2021 23 hours ago, Kas Ob. said: Should be FillArray(data, 100 * SizeOf(Integer)); Why? The C code clearly names the parameter "num_elements", so it stands to reason that it expects an "element count", not a "byte count". 23 hours ago, Kas Ob. said: As David pointed to declare the function with PInteger and pass it by PInteger(@data[0]). A dynamic array is already a pointer, so you don't need to index into the array, PInteger(data) will suffice. 1 Share this post Link to post
Guest Posted April 26, 2021 14 minutes ago, Remy Lebeau said: Why? The C code clearly names the parameter "num_elements", so it stands to reason that it expects an "element count", not a "byte count". I missed that with FillChar, you are right there. Share this post Link to post