1

I need to access macOS API calls from the C programming language rather than via Swift or Objective-C. A comparison to a Windows environment would be that on Windows, I can access calls like CreateFile(), HeapAlloc(), WriteProcessMemory(), VirtualAlloc() and etc... By simply #include <windows.h>

How can I do something similar on macOS Sierra or High Sierra? Note that I do not need to create a GUI application. I only need to access some low-level functions similar to the Windows API.

Thank you.

the_endian
  • 2,259
  • 1
  • 24
  • 49

3 Answers3

3

macOS is, at its core, a UNIX-like operating system. Its low-level API calls are generally similar to those available on Linux or other UNIX-like operating systems -- for instance, you can interact with files using open(), read(), and write(), and you can allocate memory using malloc() and free(), or at a lower level using mmap() and munmap().

A direct equivalent to Windows's WriteProcessMemory() is a little harder to get. Your best option here will be the Mach APIs like vm_read() and vm_write(). (macOS does not have the /proc/<pid>/mem interface found on Linux, and its version of the ptrace() interface is rather limited in functionality.) Keep in mind that some system processes may not be debuggable if System Integrity Protection is enabled.

3

Technically, you can call Objective-C APIs from straight C via the objc_msgSend family of functions, or by using the Objective-C APIs to resolve a method to an IMP, which you can then cast to a function type... but this is quite the pain.

The much, much better way to do this is just to mix some Objective-C code into the app. You can segregate it into a single source file, and just provide C function interfaces to your Objective-C code by doing something like:

MacSpecificStuff.h

void DoSomeMacSpecificThing();

MacSpecificStuff.m

#import <Foundation/Foundation.h> // or Cocoa/Cocoa.h, depending on what APIs you need
#import "MacSpecificStuff.h"

void DoSomeMacSpecificThing() {
    // Call a bunch of Obj-C APIs in here
}

Then just call DoSomeMacSpecificThing(); from your C code and everything's hunky-dory, since your calling code won't care what language DoSomeMacSpecificThing() is actually implemented in internally.

Charles Srstka
  • 16,665
  • 3
  • 34
  • 60
2

You can use the POSIX API because macOS is a POSIX-compliant system.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848