# C functions and native memory

To call Objective-C classes and methods, start with [Objective-C from JavaScript](/doc/objc). This guide covers known C functions and memory buffers. Incorrect addresses or signatures can crash the target process.

`C` calls in the local automation context. `RemoteC.forApp(bundleId)` selects a running app with its helper enabled; it does not launch it. `const app = RemoteC.forApp("com.apple.Preferences")` gives you the same methods as `C`. Keep buffers and function handles in their original client/session.

## C signatures

```js
const length = C.bind("strlen", {returns: "size_t", args: ["cstring"]});
console.log(length("Hello"));
length.release();
```

Supported names: `void` (return only), `bool`, `int8`, `uint8`, `int16`, `uint16`, `int32`, `uint32`, `int64`, `uint64`, `long`, `ulong`, `size_t`, `float`, `double`, `pointer`, `cstring`, `object`, `class`, `selector`, and `CGRect`, `CGPoint`, `CGSize`, `NSRange`, `UIEdgeInsets`, `CGAffineTransform`, `CGVector`, `UIOffset`. `long` and `size_t` are 64-bit. Up to 32 fixed arguments are supported.

Signatures require `returns` and `args`. For `bind()` and `call()`, optional `library` loads an absolute dylib/framework executable path. `bindAddress()` rejects `library`; omit it. `ownership:"retained"` applies only to object results whose native ownership is +1; the default is borrowed. `captureErrno:true` returns `{value, errno}` captured around that call.

Variadic calls, callbacks, arbitrary custom structures and unions are unsupported. Objective-C non-null blocks and arbitrary pointer arguments are not supported by ObjC; use a known C signature where appropriate. Symbol resolution cannot infer the correct declaration.

Structures use plain JavaScript objects with these fields:

| Type | Fields |
| --- | --- |
| CGRect | x, y, width, height |
| CGPoint / CGSize | x, y / width, height |
| NSRange | location, length |
| UIEdgeInsets | top, left, bottom, right |
| CGAffineTransform | a, b, c, d, tx, ty |
| CGVector / UIOffset | dx, dy / horizontal, vertical |

Calls are synchronous and run on the target main thread. Avoid blocking native functions. A remote timeout does not undo an action already executing; reconnect after a process restart and reacquire handles.

## Managed buffers

```js
const buffer = C.alloc(4);
try {
  buffer.writeBytes([65, 66, 67, 0]);
  console.log(buffer.readBytes());
} finally {
  buffer.release();
}
```

Managed allocations are limited to 16 MiB each and 64 MiB per session. Reads/writes allow at most 65536 bytes per operation. Use release(), not free/realloc. Releasing an external pointer handle does not free external memory. Closing either a C or ObjC client invalidates their shared references.

`bindAddress()` requires a verified absolute runtime function address in the selected process. Addresses change with ASLR and app restarts. Executable memory and alignment checks do not establish that an address is a valid function entry or that your signature is correct.
