I'm working with Apple's DiskArbitration and translated the .h files myself (attached), but I am a noob in the matter (just did take a good look at other examples).
I do keep running into a strange issue, and hopefully somebody sees or knows what I have been overlooking.
I did consult with Mr. Google, Stack Exchange, this forum, etc, etc. and have been staring at this for about a week now without finding a fix.
My environment:
MacOS Mojave 10.14.3, Lazarus 2.1.0 r60408M (SVN), and FPC 3.0.4 x86_64-darwin-cocoa (alpha).
I have defined the following:
type
DADiskAppearedCallback = procedure( disk: DADiskRef; context: univptr); cdecl;
DADiskDescriptionChangedCallback = procedure( disk: DADiskRef; keys: CFArrayRef; context: univptr); cdecl;
DADiskDisappearedCallback = procedure( disk: DADiskRef; context: univptr); cdecl;
procedure DARegisterDiskAppearedCallback( session: DASessionRef;
match: CFDictionaryRef;
callback: DADiskAppearedCallback;
context: UnivPtr ); external name '_DARegisterDiskAppearedCallback';
procedure DARegisterDiskDescriptionChangedCallback( session: DASessionRef;
match: CFDictionaryRef;
watch: CFArrayRef;
callback: DADiskDescriptionChangedCallback;
context: UnivPtr ); external name '_DARegisterDiskDescriptionChangedCallback';
procedure DARegisterDiskDisappearedCallback( session: DASessionRef;
match: CFDictionaryRef;
callback: DADiskDisappearedCallback;
context: UnivPtr ); external name '_DARegisterDiskDisappearedCallback';
procedure DiskAppeared( disk: DADiskRef; context: univptr); cdecl;
begin
// Do something when a disk appeared
end;
procedure DiskDescriptionChanged( disk: DADiskRef; keys: CFArrayRef; context: univptr); cdecl;
begin
// Do something when a disk description changed (eg. Mount, Unmount, etc)
end;
procedure DiskDisappeared( disk: DADiskRef; context: univptr); cdecl;
begin
// Do something when a disk disappeared
end;
And calling the registration functions as such:
DARegisterDiskAppearedCallback(daSession,nil,@DiskAppeared,nil);
DARegisterDiskDescriptionChangedCallback(daSession,nil,nil,@DiskDescriptionChanged,nil);
DARegisterDiskDisappearedCallback(daSession,nil,@DiskDisappeared,nil);
The DiskAppeared and DiskDisappeared work perfectly fine, even using the context parameter works as expected. I tested this by temporary commenting out the DARegisterDiskDescriptionChangedCallback call.
However when uncommenting that 3rd registration line (DARegisterDiskDisappearedCallback), the compiler throws an error:
(line 3 in this example)
Error: Incompatible type for arg no. 4: Got "<address of procedure(DADiskRef;CFArrayRef;Pointer);CDecl>", expected "<procedure variable type of procedure(DADiskRef;CFArrayRef;Pointer);CDecl>"
DiskArbitration.pas(483,11) Hint: Found declaration: DARegisterDiskDescriptionChangedCallback(DASessionRef;CFDictionaryRef;CFArrayRef;DADiskDescriptionChangedCallback;Pointer);
Note:
If I change the
DARegisterDiskDescriptionChangedCallback and
DADiskDescriptionChangedCallback definition, by removing the
keys: CFArrayRef;, like shown below, everything compiles fine and actually works - obviously this is completely wrong (the missing parameter) and as expected it will throw on a very few occasions an Access Violation error.
DADiskDescriptionChangedCallback = procedure( disk: DADiskRef; context: univptr); cdecl;
procedure DARegisterDiskDescriptionChangedCallback( session: DASessionRef;
match: CFDictionaryRef;
watch: CFArrayRef;
callback: DADiskDescriptionChangedCallback;
context: UnivPtr ); external name '_DARegisterDiskDescriptionChangedCallback';
procedure DiskDescriptionChanged( disk: DADiskRef; context: univptr); cdecl;
begin
// Do something when a disk description changed (eg. Mount, Unmount, etc)
end;
Also note that the functions
DiskAppeared,
DiskDescriptionChanged and
DiskDisappeared are in one and the same unit file, and are not part of an object or class.
I'm at a loss here trying to find what the problem may be ... does anyone know what may be wrong here?
I did check for potential double declarations, verified the functions in the Apple documentation over and over again, etc.
Isn't "
procedure(DADiskRef;CFArrayRef;Pointer);CDecl" = "
procedure(DADiskRef;CFArrayRef;Pointer);CDecl" ?
Seems that way with the DiskAppeared and DiskDisappeared calls, yet doesn't compile with DiskDescriptionChanged.
Why does it work with 2 out of 3 times?