将 Objective-C 代码转换为 Delphi (XE8)
Converting Objective-C code to Delphi (XE8)
为了跟踪我的代码的各个部分分配了多少内存,我发现了这个 objective-C 代码 (here),我想在 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?
(我也许可以自己转换定义,但是我在哪里可以找到 headers?)
PS。我知道这是一种追踪内存的原始方式,但我还没有找到更好的解决方案。 Xcode Instruments
告诉我我的应用程序调用了 malloc 180.000 次,但它没有说明是什么代码或 objects 启动了它。此信息可能会丢失,因为我使用 Delphi.
更新
下面是我对函数的翻译和实现。它适用于 iOS 模拟器,并且在针对 32 位 iOS 设备时,但它不适用于 64 位 iOS 设备(return 值为 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
的子文件夹中找到 headers。
我想将它们复制到我硬盘上的另一个文件夹中,以保留当前版本 XCode 中未包含的旧版本 SDK。这样我也可以使用 Spotlight 快速找到包含特定函数或定义的文件。
为了跟踪我的代码的各个部分分配了多少内存,我发现了这个 objective-C 代码 (here),我想在 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? (我也许可以自己转换定义,但是我在哪里可以找到 headers?)
PS。我知道这是一种追踪内存的原始方式,但我还没有找到更好的解决方案。 Xcode Instruments
告诉我我的应用程序调用了 malloc 180.000 次,但它没有说明是什么代码或 objects 启动了它。此信息可能会丢失,因为我使用 Delphi.
更新
下面是我对函数的翻译和实现。它适用于 iOS 模拟器,并且在针对 32 位 iOS 设备时,但它不适用于 64 位 iOS 设备(return 值为 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
的子文件夹中找到 headers。
我想将它们复制到我硬盘上的另一个文件夹中,以保留当前版本 XCode 中未包含的旧版本 SDK。这样我也可以使用 Spotlight 快速找到包含特定函数或定义的文件。