1

Data block:

PMyDataBlock = ^MyDataBlock;
MyDataBlock = record
  // .............
end;

Is a following definition:

function MyFunction(const pstSettings: MyDataBlock): HRESULT; stdcall; external 'MyLib.dll' name 'MyFunction';

a full equivalent of this?:

function MyFunction(pstSettings: PMyDataBlock): HRESULT; stdcall; external 'MyLib.dll' name 'MyFunction';
Paul
  • 25,812
  • 38
  • 124
  • 247
  • 1
    `const` implies special semantics for Delphi compiler only. I wouldn't use it in external function declaration. And, no, it's not equivalent to pointer. That depends on the type of the argument. E.g. `const Integer` is not `PInteger`, but there are more ... – Peter Wolf May 21 '21 at 14:08
  • 2
    See also [What difference does it make when I use “const” in a procedure's parameter?](https://stackoverflow.com/questions/11001477/what-difference-does-it-make-when-i-use-const-in-a-procedures-parameter). – Peter Wolf May 21 '21 at 14:09
  • Peter Wolf, the external function is already declared and is written in C. – Paul May 21 '21 at 14:09
  • I meant external function declaration in your *Delphi* code (where you refer to a function in DLL). – Peter Wolf May 21 '21 at 14:11
  • Ok, then I'll stick with pointers. In this case I can even pass a NIL argument. – Paul May 21 '21 at 14:13
  • 3
    Since Delphi 10.4 you can force the compiler to pass a [constant parameter](http://docwiki.embarcadero.com/RADStudio/en/Parameters_(Delphi)#Constant_Parameters) by reference using `[Ref]` decorator. You should be still able to pass `nil` using `PMyDataBlock(nil)^`, although I didn't experiment with that. I still don't recommend using it in external functions. – Peter Wolf May 21 '21 at 14:21

1 Answers1

1

The short answer is "No, it is not"

In your case, your record may or may not be passed by reference. The size of the record is 1 of the factor I know of that affect that behavior. If your record is 4 bytes or less, I believe it will be passed by value, otherwise, it will be passed by reference. I don't believe this behavior is contractual (In other word, Embarcadero is free to change it at any time in the future). In other words, it's a bad idea to use const parameter to call an external function.

If you want to pass your record by reference, the proper way to do would be to declare it var

function MyFunction(var pstSettings: MyDataBlock): HRESULT; stdcall; external 'MyLib.dll' name 'MyFunction';

or pass it as a pointer.

Ken Bourassa
  • 6,363
  • 1
  • 19
  • 28
  • 1
    A const record size smaller or equal to the size of a pointer, means that the compiler is free to pass it by value. Unless you use the [ref] decorator introduced in recent Delphi versions. – LU RD May 21 '21 at 15:57