1
votes

Cannot obtain CFStringRef value from iOS API function (framework) in Delphi 10.3 Rio

// external call bridge function to iOS:
function MIDIObjectGetStringProperty(obj: MIDIObjectRef;
            propertyID: CFStringRef;
            out str: CFStringRef):OSStatus; cdecl; external libCoreMidi name _PU + 'MIDIObjectGetStringProperty'; 

Function MIDIObjectGetStringProperty (iOS CoreMIDI function) return in str:CFStringRef name of MIDI ports ...

How can I obtain value of CFString variable in Delphi? In this example str:CFStringRef value?

I try it in my func.:

function getDisplayName(obj: MIDIEndpointRef):string;
var 
    EndPointName: CFStringRef;
    i:integer;
begin
    //EndPointName:= nil; // when I assign nil value, function return i=-50 otherwise raise Access Violation error ...

    i := MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName , EndPointName); --> AV error !!!

    //in EndPointName should be returned CFStringRef value from iOS 

    getDisplayName :=  CFToDelphiString(EndPointName); // convert to string
end;

Probably EndPointName need to be allocated ... else I give AV error. Please got someone solution how obtain ANY CFStringRef value from iOS framework and convert to string? Thanx.

Adds:

I build crossplatform (iOS, Android, W64) app in Delphi Rio via FireMonkey frameforks api - for CoreMIDI I use this interface https://github.com/FMXExpress/ios-object-pascal-wrapper/blob/master/iOSapi.CoreMIDI.pas

So the externall call and constants are defined in iOSapi.CoreMIDI there:

function MIDIObjectGetStringProperty (obj: MIDIObjectRef; propertyID: CFStringRef; str: CFStringRef) : OSStatus; cdecl; external libCoreMIDI name _PU + 'MIDIObjectGetStringProperty';

and iOS pointer const:

function kMIDIPropertyDisplayName: Pointer;
begin
  Result := CocoaPointerConst(libCoreMIDI, 'kMIDIPropertyDisplayName');
end;

Otherwies compiled app work on real iOS (iPad) very well (reading MIDI message from connected MIDI keyboard) based on this solution https://pjstrnad.com/reading-data-midi-keyboard-ios-probably-also-mac/

obj: MIDIObjectRef is source pointer from source:= MIDIGetSource(ci);

Problem is calling API function MIDIObjectGetStringProperty. In pointer str: CFStringRef (EndPointName) should be VALUE of MIDIportNAME. I cannot obtain this value and parse to delphi string ...

I tried declared this poiter CFStringRef as:

var
EndPointName: pointer;
EndPointName1: array of Byte;
EndPointName2: TBytes;
EndPointName3: TPtrWrapper;
M: TMarshaller;

and construction as:

SetLength(EndPointName1, 255);
GetMem(EndPointName2,255);
EndPointName3 := M.AllocMem(255);

i := MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName , @EndPointNameX);

--> nothing works, AV error !!!

I thing it must be solution how to obtain CFStringRef and convert to delphi string ...

1
How are obj and kMIDIPropertyDisplayName obtained? It's important to show all code that we cannot determine for ourselves.Dave Nottage
XE doesn't support iOSDavid Heffernan
Thanks for reaction. I adds more information.roland_sax
Please stop referring to XE. That version of Delphi predates mobile support. You are using 10.3 Rio. Please correct the text.David Heffernan
Oh. Sorry corrected ...roland_sax

1 Answers

1
votes

The kMIDIPropertyDisplayName is broken on iOS, but you can replace it with CFSTR('displayName'). It works for me. So your function looks like this:

function getDisplayName(aEndPointRef: MIDIEndpointRef):string;
var 
  LEndPointName: CFStringRef;
  i:integer;
begin
  getDisplayName := 'MIDI endpoint';
  LEndPointName:= nil; 
  i := MIDIObjectGetStringProperty(aEndPointRef, CFSTR('displayName'), LEndPointName);
  if (i=0) and (LEndPointName<>nil) then
    getDisplayName := CFStringRefToStr(LEndPointName);
end;

Add Macapi.CoreFoundation and Macapi.Helpers to your USES clause to get access to CFSTR and CFStringRefToStr