簡體   English   中英

將 Objective-C 代碼轉換為 Delphi (XE8)

[英]Converting Objective-C code to Delphi (XE8)

為了跟蹤我的代碼的各個部分分配了多少內存,我找到了這個目標 C 代碼( 這里),我想在 Delphi XE8 中運行它:

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)&info,
                                   &size);
    if( kerr == KERN_SUCCESS ) {
        NSLog(@"Memory in use (in bytes): %u", info.resident_size);
    }
}

這段代碼只是讀取程序當前使用的內存量並記錄下來。 我將使用它來檢測在調用代碼的不同部分時內存使用量增長了多少。

它包括Mach.h ,並且 Delphi 中有一個Macapi.Mach.pas單元,但它沒有實現這里使用的任何定義。

(NSLog 函數日志已經實現: iOSApi.Foundation.NSLog((StrToNSStr(aMessage) as ILocalObject).GetObjectID)

這段代碼應該如何轉換為Delphi XE8? (我也許可以自己轉換定義,但是我在哪里可以找到標題?)

附注。 我知道這是一種跟蹤內存的原始方法,但我還沒有找到更好的解決方案。 Xcode Instruments告訴我,我的應用程序調用了 malloc 180.000 次,但它沒有指出是什么代碼或對象啟動了它。 由於我使用 Delphi,此信息可能會丟失。

更新

下面是我對該函數的翻譯和實現。 它適用於 iOS 模擬器和定位 32 位 iOS 設備時,但它不適用於 64 位 iOS 設備(返回值為 4)。

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)&info,
                                   &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.

對我來說,它適用於 32 位就足夠了,但為了完整起見,如果您發現應該更改哪些內容以使其適用於 64 位,請發表評論(如果您在實現中發現其他錯誤)。

您可以在/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer的子文件夾中找到標題。

我喜歡將這些復制到我的 HDD 上的另一個文件夾中,以保留當前版本的 XCode 中未包含的舊版本 SDK。 這樣我還可以使用 Spotlight 來快速找到包含特定函數或定義的文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM