title: Converting Objective-C code to Delphi (XE8)
body: <p>To trace how much memory various parts of my code allocates, I found this objective-C code (<a href="https://stackoverflow.com/questions/787160/programmatically-retrieve-memory-usage-on-iphone%20Here">here</a>), that I want to run in Delphi XE8: </p>
  
  <pre class="lang-c prettyprint-override"><code>void report_memory(void)
  {
      struct mach_task_basic_info info;
      mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT;
      kern_return_t kerr = task_info(mach_task_self(),
                                     MACH_TASK_BASIC_INFO,
                                     (task_info_t)&amp;info,
                                     &amp;size);
      if( kerr == KERN_SUCCESS ) {
          NSLog(@"Memory in use (in bytes): %u", info.resident_size);
      }
  }
  </code></pre>
  
  <p>This code simply reads the current amount of memory used by the program and logs it. I will use it to detect how much memory usage grows when calling different parts of my code. </p>
  
  <p>It includes <code>Mach.h</code>, and there is a <code>Macapi.Mach.pas</code> unit in Delphi, but it does not implement any of the definitions used here.</p>
  
  <p>(The NSLog function log is implemented already: <code>iOSApi.Foundation.NSLog((StrToNSStr(aMessage) as ILocalObject).GetObjectID)</code>)</p>
  
  <p>How should this code be converted to Delphi XE8?
  (I might be able to convert the definitions my self, but where do I find the headers?)</p>
  
  <p>PS. I know this is a primitive way of tracing memory, but I have not found any better solution. The <code>Xcode Instruments</code>, tells me that my app calls malloc 180.000 times, but it does not indicate what code or objects initiated it. This information might be lost because I use Delphi.</p>
  
  <h2>Update</h2>
  
  <p>Here is my translation and implementation of the function. It works with the iOS simulator and when targeting a 32bit iOS device, but it does NOT work on a 64 bit iOS device (return value is 4).</p>
  
  <pre class="lang-pascal prettyprint-override"><code>unit uMachExt;
  
  interface
  
  uses Macapi.Mach, Posix.Base;
  
  type
    integer_t = Integer;
    natural_t = NativeInt;
    mach_vm_size_t = UInt64;
    //typedef int policy_t
    policy_t = Integer;
  
    //type time_value_t = struct[2] of integer_t;
    time_value_t = array[0..1] of Integer; //0:seconds, 1:microseconds
  
    //typedef natural_t mach_msg_type_number_t
    mach_msg_type_number_t = natural_t;
  
    //type kern_return_t = int;
    kern_return_t = integer;
  
    //typedef natural_t   task_flavor_t;
    task_flavor_t = natural_t;
  
    // typedef    integer_t   *task_info_t;       /* varying array of int */
    task_info_t = array of integer_t;
  
    {#define MACH_TASK_BASIC_INFO     20         /* always 64-bit basic info */
    struct mach_task_basic_info {
            mach_vm_size_t  virtual_size;       /* virtual memory size (bytes) */
            mach_vm_size_t  resident_size;      /* resident memory size (bytes) */
            mach_vm_size_t  resident_size_max;  /* maximum resident memory size (bytes) */
            time_value_t    user_time;          /* total user run time for
                                                   terminated threads */
            time_value_t    system_time;        /* total system run time for
                                                   terminated threads */
            policy_t        policy;             /* default policy for new threads */
            integer_t       suspend_count;      /* suspend count for task */
    }
    mach_task_basic_info = Record
          virtual_size: mach_vm_size_t  ;       //* virtual memory size (bytes) */
          resident_size: mach_vm_size_t  ;      //* resident memory size (bytes) */
          resident_size_max: mach_vm_size_t  ;  //* maximum resident memory size (bytes) */
          user_time: time_value_t    ;          //* total user run time for terminated threads */
          system_time: time_value_t    ;        //* total system run time forterminated threads */
          policy: policy_t        ;             //* default policy for new threads */
          suspend_count: integer_t;               //* suspend count for task */
    end;
  
  const
    cMACH_TASK_BASIC_INFO = 20;
    {typedef struct mach_task_basic_info       mach_task_basic_info_data_t;
    #define MACH_TASK_BASIC_INFO_COUNT   \
                  (sizeof(mach_task_basic_info_data_t) / sizeof(natural_t))}
    cMACH_TASK_BASIC_INFO_COUNT = SizeOf(mach_task_basic_info) div sizeof(natural_t);
  
    {
    #ifdef    mig_external
    mig_external
    #else
    extern
    #endif    /* mig_external */
    kern_return_t task_info
    (
      task_name_t target_task,
      task_flavor_t flavor,
      task_info_t task_info_out,
      mach_msg_type_number_t *task_info_outCnt
    );
    }
  
    function task_info( target_task: task_name_t;
                        flavor: task_flavor_t;
                        var task_info_out: mach_task_basic_info;
                        var task_info_outCnt: mach_msg_type_number_t)  : kern_return_t;
      cdecl external libc name _PU + 'task_info';
  
    function GetMemoryUsage: Integer;
  
  implementation
  
  {   struct mach_task_basic_info info;
      mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT;
      kern_return_t kerr = task_info(mach_task_self(),
                                     MACH_TASK_BASIC_INFO,
                                     (task_info_t)&amp;info,
                                     &amp;size);
  }
  
  function GetMemoryUsage: Integer;
  var info: mach_task_basic_info;
      size: mach_msg_type_number_t;
      kerr: kern_return_t;
  begin
    Result := 0;
    size := cMACH_TASK_BASIC_INFO_COUNT;
    kerr := task_info(mach_task_self, cMACH_TASK_BASIC_INFO, info, size);
    if kerr=0 then
      result := info.resident_size;
  end;
  
  end.
  </code></pre>
  
  <p>It is enough for me that it works with 32 bit, but for completeness, if you find what should be changed to make it work with 64 bit, please comment (also if you find other errors in the implementation).</p>