Der folgende Code empfängt MIDI-Daten von einem Musikinstrument, das mit dem iOS-Gerät verbunden ist. Es funktioniert gut auf einem 32-Bit-iOS-Gerät. Bei 64 Bit wird die Callback-Funktion auch für jedes Event aufgerufen, aber die in 'pktlist' empfangenen Daten sind ungültig. Was ist falsch?Warum funktioniert dieser Code unter iOS 32 Bit, aber nicht unter 64 Bit?
Die Daten, die ich in MidiReadProc
erhalten ist immer das gleiche auf einem 64-Bit-Gerät, und es ist eindeutig falsch, da die Länge würde normalerweise nie 0 sein:
pktlist^.numPackets = 1
lPacket.MIDItimestamp=$E4FE000100000961
lPacket.length=$0000
lPacket.data[0]=$00
Die Callback-Funktion:
procedure MidiReadProc(pktlist: MIDIPacketListRef; refCon, connRefCon: Pointer); cdecl;
var
lPacket: MIDIPacket;
lPacketRef: MIDIPacketRef;
j: Integer;
lPtr: ^Byte;
begin
lPacketRef := MIDIPacketRef(@(pktlist^.Packet[0]));
for j := 0 to pktlist^.numPackets-1 do
begin
lPacket := lPacketRef^;
if (lPacket.length > 0) and (lPacket.data[0] <> $F0) then
//handle data here
//translation of the MIDIPacketNext Macro:
lPtr := @lPacketRef^.data[lPacketRef^.length];
lPacketRef := MIDIPacketRef((UInt64(lPtr) + 3) and (not 3));
end;
end;
Falls es in die Header-Übersetzung zusammenhängen könnte, ist hier die Übersetzung:
Auszug aus CoreMIDI.h:
012.351.typedef UInt64 MIDITimeStamp;
#pragma pack(push, 4)
struct MIDIPacket
{
MIDITimeStamp timeStamp;
UInt16 length;
Byte data[256];
};
typedef struct MIDIPacket MIDIPacket;
struct MIDIPacketList
{
UInt32 numPackets;
MIDIPacket packet[1];
};
typedef struct MIDIPacketList MIDIPacketList;
#pragma pack(pop)
typedef void
(*MIDIReadProc)(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon);
#if TARGET_CPU_ARM || TARGET_CPU_ARM64
// MIDIPacket must be 4-byte aligned
#define MIDIPacketNext(pkt) ((MIDIPacket *)(((uintptr_t)(&(pkt)->data[(pkt)->length]) + 3) & ~3))
Auszug aus CoreMIDI.pas (die Übersetzung von CoreMIDI.h von Pavel Jiri Strnad gemacht und is available here):
MIDITimeStamp = UInt64;
MIDIPacket = record
timeStamp: MIDITimeStamp;
length: UInt16;
data: array [0..255] of Byte;
end;
MIDIPacketRef = ^MIDIPacket;
MIDIPacketList = record
numPackets: UInt32;
packet: array [0..0] of MIDIPacket;
end;
MIDIPacketListRef = ^MIDIPacketList;
MIDIReadProc = procedure (pktlist: MIDIPacketListRef; readProcRefCon: pointer; srcConnRefCon: pointer); cdecl;
Update:
Wie in den Kommentaren von David vorgeschlagen Hier sind die Feldversätze der Datensätze:
MIDIPacketList
Offsets:
64 bit Align 8: numPackets=0 packet=8 <- this was the one causing problems
64 bit Align 1: numPackets=0 packet=4
32 bit Align 8: numPackets=0 packet=4
32 bit Align 1: numPackets=0 packet=4
MIDIPacket
Offsets:
64 bit Align 8: timeStamp=0 length=8 data=10
64 bit Align 1: timeStamp=0 length=8 data=10
32 bit Align 8: timeStamp=0 length=8 data=10
32 bit Align 1: timeStamp=0 length=8 data=10
Ich möchte nicht einen Tag Krieg starten, aber das hat wirklich nichts mit Firefemonkey zu tun. –
Haben Sie überprüft, ob die Strukturausrichtung korrekt ist? –
Das hat absolut nichts mit FireMonkey zu tun. Es ist eine Interop-Frage. Ich weiß nichts über FireMonkey, aber viel über Interop. Möchtest du, dass ich es ignoriere, weil ich kein FireMonkey-Entwickler bin? –