Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2008-09

Carbon: i386 and PPC API differences

4 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

EarMaster - Bent Olsen

Hi all,

I use Xcode to find samples of codes and try to make it work on FPC/Lazarus. One example opens an AUGraph and send MIDI messages - a small sample. It calls AUGraphNewNode which returns a node from 1 to n, and it works perfectly in FPC on Carbon/i386, and of course for Xcode on the same machine.

The same code works fine in Xcode on Carbon/PowerPC, but does not return any nodes in FPC on Carbon/PowerPC.

I've just started on working with PowerPC, so I thought I'm obviously is missing out something vital, perhaps with the record definition used by AUGraphNewNode.

I've learned about SetExceptionMask and floating points today when using PowerPC, so maybe I need to handle the records differently also? I know about little and big endian, but this shouldn't be necessary?

Or perhaps I should define the external call differently on PowerPC?

I've include code snips below, and any hints will be much appreciated. TIA, and best regards,
Normann

// -------- Code snips
// Pascal
type
  ComponentDescription = record
    componentType: OSType;
    componentSubType: OSType;
    componentManufacturer: OSType;
    componentFlags: UInt32;
    componentFlagMask: UInt32;
  end;
function AUGraphNewNode(inGraph: AUGraph; const inDescription:
ComponentDescription;
  inClassDataSize: LongWord; inClassData : Pointer; var outNode : AUNode):
OSStatus;
  external name '_AUGraphNewNode'; mwpascal; //
AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER;
var
  _Graph: AUGraph;
  _CD: ComponentDescription;
  _Node: AUNode;
begin
  NewAUGraph(_Graph);
  _CD.componentType := kAudioUnitComponentType;
  _CD.componentSubType := kAudioUnitSubType_MusicDevice;
  _CD.componentManufacturer := kAudioUnitID_DLSSynth;
  _CD.componentFlags := 0;
  _CD.componentFlagsMask := 0;
  AUGraphNewNode(_Graph, _CD, 0, nil, _Node); // Node returns zero, but no
OSError

// C++
struct ComponentDescription {
OSType componentType; /* A unique 4-byte code indentifying the command set */
OSType componentSubType; /* Particular flavor of this instance */
OSType componentManufacturer; /* Vendor indentification */ unsigned long componentFlags; /* 8 each for Component,Type,SubType,Manuf/revision */
unsigned long componentFlagsMask; /* Mask for specifying which flags to consider in search, zero during registration */ };

extern OSStatus AUGraphNewNode(AUGraph inGraph, const ComponentDescription *inDescription,
UInt32 inClassDataSize, const void *inClassData, AUNode *outNode)

  AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER;
{
  AUGraph _Graph;
  ComponentDescription _CD;
  AUNode _Node;
  NewAUGraph(@_Graph);
  _CD.componentType = kAudioUnitComponentType;
  _CD.componentSubType = kAudioUnitSubType_MusicDevice;
  _CD.componentManufacturer = kAudioUnitID_DLSSynth;
  _CD.componentFlags = 0;
  _CD.componentFlagsMask = 0;
  AUGraphNewNode(_Graph, &_CD, 0, NULL, &_Node); /* Node returns 1
}
Jonas Maebe
to EarMaster - Bent Olsen
EarMaster - Bent Olsen wrote 31 lines
I use Xcode to find samples of codes and try to make it work on FPC/ Lazarus. One example opens an AUGraph and send MIDI messages - a small sample. It calls AUGraphNewNode which returns a node from 1 to n, and it works perfectly in FPC on Carbon/i386, and of course for Xcode on the same machine. The same code works fine in Xcode on Carbon/PowerPC, but does not return any nodes in FPC on Carbon/PowerPC. // -------- Code snips // Pascal type ComponentDescription = record componentType: OSType; componentSubType: OSType; componentManufacturer: OSType; componentFlags: UInt32; componentFlagMask: UInt32; end; function AUGraphNewNode(inGraph: AUGraph; const inDescription: ComponentDescription; inClassDataSize: LongWord; inClassData : Pointer; var outNode : AUNode): OSStatus; external name '_AUGraphNewNode'; mwpascal; // AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER;

"const inDescription: ComponentDescription" is wrong, because FPC does not guarantee that this will be passed by reference (especially in case of C imports, because in C "const" also means "pass by value"). Either use a pointer type, or use "var" instead. There is no constvar or similar specifier.

Also add {$packrecords C} to your source to ensure that the records are properly packed, and translate "unsigned long" using the "culong" type from the ctypes unit rather than using uint32 ("unsigned long" is not the same as uint32 on all platforms, e.g. it's different on 64 bit Mac OS X).

Jonas

EarMaster - Bent Olsen
to Jonas Maebe
Show quoted text 18 lines
-----Original Message----- From: [mailto:fpc-pascal- On Behalf Of Jonas Maebe Sent: 29. september 2008 16:26 To: FPC-Pascal users discussions Subject: Re: [fpc-pascal] Carbon: i386 and PPC API differences "const inDescription: ComponentDescription" is wrong, because FPC does not guarantee that this will be passed by reference (especially in case of C imports, because in C "const" also means "pass by value"). Either use a pointer type, or use "var" instead. There is no constvar or similar specifier. Also add {$packrecords C} to your source to ensure that the records are properly packed, and translate "unsigned long" using the "culong" type from the ctypes unit rather than using uint32 ("unsigned long" is not the same as uint32 on all platforms, e.g. it's different on 64 bit Mac OS X).

Thanks for the input, Jonas, and I went through all the declarations and found that AUNode from the AUGraph.h was wrongly specified as "Integer", and should be SInt32 as used in the C sample.

That did a huge difference, and the sample is now works.

Thanks again,
Normann

Jonas
Jonas Maebe
to EarMaster - Bent Olsen
EarMaster - Bent Olsen wrote 14 lines
> -----Original Message----- > From: [mailto:fpc-pascal- > On Behalf Of Jonas Maebe > Sent: 29. september 2008 16:26 > To: FPC-Pascal users discussions > Subject: Re: [fpc-pascal] Carbon: i386 and PPC API differences > > "const inDescription: ComponentDescription" is wrong, because FPC > does > not guarantee that this will be passed by reference (especially in > case of C imports, because in C "const" also means "pass by value"). > Either use a pointer type, or use "var" instead. There is no constvar > or similar specifier. >

I made a mistake here: when using the "mwpascal" calling convention, "const" in combination with a record does in fact always mean "pass by reference", because that's the meaning it also had with MetroWerks Pascal.

Show quoted text 15 lines
> Also add {$packrecords C} to your source to ensure that the records > are properly packed, and translate "unsigned long" using the "culong" > type from the ctypes unit rather than using uint32 ("unsigned long" > is > not the same as uint32 on all platforms, e.g. it's different on 64 > bit > Mac OS X). Thanks for the input, Jonas, and I went through all the declarations and found that AUNode from the AUGraph.h was wrongly specified as "Integer", and should be SInt32 as used in the C sample. That did a huge difference, and the sample is now works.

That also explains why it worked on Intel and not on PowerPC: on Intel, interpreting a 32 bit integer as a 16 bit integer is no problem as long as the value is < 65536. On PowerPC, such a declaration mismatch will however result in reading the upper 16 bits of the 32 bit value.

Jonas