or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

android-platform.mdindex.mdios-platform.mdnative-interop.mdnativescript-widgets.md

native-interop.mddocs/

0

# Native Interoperability

1

2

Advanced native code integration layer providing pointer arithmetic, memory management, type conversion, and native function calls specifically for iOS platform development. Essential for low-level native iOS API access.

3

4

## Capabilities

5

6

### Pointer Management

7

8

Core pointer operations for direct memory access and native API integration.

9

10

```typescript { .api }

11

declare module interop {

12

/**

13

* A type that represents a void* pointer for direct memory access

14

*/

15

interface Pointer {

16

/**

17

* Create a new pointer with the given offset

18

* @param offset - The offset in bytes

19

*/

20

new(offset: number);

21

22

/**

23

* Create a new pointer by adding an offset to the current pointer

24

* @param offset - The offset in bytes

25

* @returns New pointer with added offset

26

*/

27

add(offset: number): Pointer;

28

29

/**

30

* Create a new pointer by removing an offset from the current pointer

31

* @param offset - The offset in bytes

32

* @returns New pointer with subtracted offset

33

*/

34

subtract(offset: number): Pointer;

35

36

/**

37

* Convert the value of this instance to a number

38

* @returns Numeric representation of the pointer address

39

*/

40

toNumber(): number;

41

}

42

43

var Pointer;

44

45

/**

46

* A pointer that will free the memory it points to automatically when garbage collected

47

*/

48

interface AdoptedPointer extends Pointer {

49

}

50

}

51

```

52

53

**Usage Examples:**

54

55

```typescript

56

// Create and manipulate pointers

57

const ptr = new interop.Pointer(0x1000);

58

const offsetPtr = ptr.add(64); // Add 64 bytes

59

const backPtr = offsetPtr.subtract(32); // Subtract 32 bytes

60

61

// Convert pointer to numeric address

62

const address = ptr.toNumber();

63

console.log(`Pointer address: 0x${address.toString(16)}`);

64

```

65

66

### Memory Allocation

67

68

Memory management functions for allocating and releasing native memory.

69

70

```typescript { .api }

71

declare module interop {

72

/**

73

* Make the pointer adopted - it will hold its memory automatically

74

* @param ptr - The pointer to adopt

75

* @returns AdoptedPointer that will auto-free memory

76

*/

77

function adopt(ptr: Pointer): AdoptedPointer;

78

79

/**

80

* Allocate memory block

81

* @param size - The size in bytes to allocate

82

* @returns AdoptedPointer to allocated memory

83

*/

84

function alloc(size: number): AdoptedPointer;

85

86

/**

87

* Release the memory of a pointer (should not be adopted)

88

* @param ptr - Pointer to the memory to free

89

*/

90

function free(ptr: Pointer): void;

91

92

/**

93

* Return the size of the provided type

94

* @param type - Class constructor, instance, struct, reference, protocol, or function

95

* @returns Size in bytes of the type

96

*/

97

function sizeof(type: any): number;

98

99

/**

100

* Get a pointer to the backing native object from a JavaScript object

101

* @param instance - Class constructor, instance, struct, reference, protocol, function, or block

102

* @returns Pointer to the native object

103

*/

104

function handleof(instance: any): Pointer;

105

106

/**

107

* Wrap an NSData instance in an ArrayBuffer

108

* @param data - NSData instance to wrap

109

* @returns ArrayBuffer wrapping the data

110

*/

111

function bufferFromData(data: NSData): ArrayBuffer;

112

}

113

```

114

115

**Usage Examples:**

116

117

```typescript

118

// Allocate and manage memory

119

const buffer = interop.alloc(1024); // Allocate 1KB, auto-freed

120

const rawPtr = new interop.Pointer(0x2000);

121

const adoptedPtr = interop.adopt(rawPtr); // Now auto-freed

122

123

// Get size information

124

const nsStringSize = interop.sizeof(NSString);

125

const intSize = interop.sizeof(interop.types.int32);

126

127

// Get native handle

128

const nsString = NSString.stringWithString("Hello");

129

const handle = interop.handleof(nsString);

130

131

// Convert NSData to ArrayBuffer

132

const nsData = NSData.dataWithContentsOfFile("/path/to/file");

133

const buffer = interop.bufferFromData(nsData);

134

```

135

136

### Reference Types

137

138

Typed references for passing values by reference to native functions.

139

140

```typescript { .api }

141

declare module interop {

142

/**

143

* A type that wraps a pointer and allows read/write operations on its value

144

*/

145

interface Reference<T> {

146

/** The referenced value */

147

value: T;

148

}

149

150

/**

151

* Reference constructor for creating typed references

152

*/

153

var Reference: {

154

/**

155

* Create a new reference around a value

156

* @param value - JavaScript value to initialize the reference

157

* @returns Reference wrapping the value

158

*/

159

new <T>(value?: T): Reference<T>;

160

161

/**

162

* Create a reference from pointer with given type

163

* @param type - The type to interpret the pointer as

164

* @param data - Pointer to the data

165

* @returns Typed reference to the pointer data

166

*/

167

new <T>(type: Type<T>, data: Pointer): Reference<T>;

168

169

/**

170

* Create a new reference around a value with explicit type

171

* @param type - The type to interpret the value as

172

* @param value - Value to reference

173

* @returns Typed reference to the value

174

*/

175

new <T>(type: Type<T>, value: any): Reference<T>;

176

177

/**

178

* Access values using pointer arithmetic

179

*/

180

[index: number]: any;

181

}

182

}

183

```

184

185

**Usage Examples:**

186

187

```typescript

188

// Create references for passing by reference

189

const intRef = new interop.Reference<number>(42);

190

const stringRef = new interop.Reference<string>("Hello");

191

192

// Use with native functions that expect references

193

someNativeFunction(intRef);

194

console.log(intRef.value); // May be modified by native function

195

196

// Create typed references from pointers

197

const ptr = interop.alloc(interop.sizeof(interop.types.int32));

198

const typedRef = new interop.Reference(interop.types.int32, ptr);

199

typedRef.value = 100;

200

201

// Array-style access for pointer arithmetic

202

typedRef[0] = 100; // Same as typedRef.value = 100

203

typedRef[1] = 200; // Next int32 in memory

204

```

205

206

### Function References

207

208

Native function pointer support for callback scenarios, including Objective-C blocks.

209

210

```typescript { .api }

211

declare module interop {

212

interface FunctionReference<T> {

213

(...params);

214

}

215

216

/**

217

* Create a function reference that can be marshalled as a native function pointer

218

* The JavaScript reference must be held alive as long as the native code needs it

219

*/

220

var FunctionReference: {

221

new <T>(func: T): FunctionReference<T>;

222

}

223

224

/**

225

* Objective-C Block type for callback scenarios

226

* Blocks are Objective-C's closure implementation

227

*/

228

interface Block<T> {

229

(...params);

230

}

231

232

/**

233

* Create an Objective-C block from a JavaScript function

234

* The JavaScript reference must be held alive as long as the native code needs it

235

*/

236

var Block: {

237

new <T>(func: T): Block<T>;

238

}

239

}

240

```

241

242

**Usage Examples:**

243

244

```typescript

245

// Create function reference for native callbacks

246

const callback = (result: number) => {

247

console.log(`Native callback result: ${result}`);

248

};

249

250

const funcRef = new interop.FunctionReference(callback);

251

252

// Pass to native function expecting callback

253

someNativeFunctionWithCallback(funcRef);

254

// Keep funcRef alive as long as native code might call it

255

256

// Create Objective-C block for iOS callbacks

257

const blockCallback = (success: boolean, error: NSError) => {

258

if (success) {

259

console.log("Operation completed successfully");

260

} else {

261

console.log(`Operation failed: ${error.localizedDescription}`);

262

}

263

};

264

265

const block = new interop.Block(blockCallback);

266

267

// Pass block to Objective-C method expecting a completion handler

268

someNSObjectMethod.performOperationWithCompletion(block);

269

// Keep block reference alive during async operation

270

```

271

272

### Type System

273

274

Comprehensive type definitions for native type conversion and marshalling.

275

276

```typescript { .api }

277

declare module interop {

278

interface Type<T> {

279

(ptr: Pointer): T;

280

}

281

282

var types: {

283

/** Void type */

284

"void": Type<void>;

285

/** Boolean type */

286

bool: Type<boolean>;

287

/** 8-bit signed integer */

288

int8: Type<number>;

289

/** 8-bit unsigned integer */

290

uint8: Type<number>;

291

/** 16-bit signed integer */

292

int16: Type<number>;

293

/** 16-bit unsigned integer */

294

uint16: Type<number>;

295

/** 32-bit signed integer */

296

int32: Type<number>;

297

/** 32-bit unsigned integer */

298

uint32: Type<number>;

299

/** 64-bit signed integer */

300

int64: Type<number>;

301

/** 64-bit unsigned integer */

302

uint64: Type<number>;

303

/** 32-bit floating point */

304

float: Type<number>;

305

/** 64-bit floating point */

306

double: Type<number>;

307

308

/** UTF-8 C string type */

309

UTF8CString: Type<Reference<number>>;

310

/** Unicode character type */

311

unichar: Type<string>;

312

313

/** Objective-C id type */

314

id: Type<any>;

315

/** Objective-C protocol type */

316

protocol: Type<any>;

317

/** Objective-C class type */

318

"class": Type<any>;

319

/** Objective-C selector type */

320

selector: Type<string>;

321

}

322

}

323

```

324

325

**Usage Examples:**

326

327

```typescript

328

// Use primitive types

329

const intSize = interop.sizeof(interop.types.int32);

330

const doubleSize = interop.sizeof(interop.types.double);

331

332

// Create typed references

333

const intRef = new interop.Reference(interop.types.int32, 42);

334

const floatRef = new interop.Reference(interop.types.float, 3.14);

335

336

// Work with C strings

337

const cStringRef = new interop.Reference(interop.types.UTF8CString);

338

```

339

340

### Struct Types

341

342

Support for C struct definitions and manipulation.

343

344

```typescript { .api }

345

declare module interop {

346

/**

347

* A type for JavaScript constructors for C structs

348

*/

349

interface StructType<T> extends Type<T> {

350

/**

351

* Create a new instance of the struct

352

*/

353

new(): T;

354

355

/**

356

* Create a new instance and initialize from provided object fields

357

* @param obj - Initializer object

358

* @returns New struct instance

359

*/

360

new(obj: T): T;

361

362

/**

363

* Create a new struct by copying memory from pointer

364

* @param obj - Pointer to struct data

365

* @returns New struct instance

366

*/

367

new(obj: Pointer): T;

368

369

/**

370

* Check two structs for equality

371

* @param left - First struct to compare

372

* @param right - Second struct to compare

373

* @returns True if structs are equal

374

*/

375

equals(left: T, right: T): boolean;

376

}

377

}

378

```

379

380

**Usage Examples:**

381

382

```typescript

383

// Define a struct type (example - actual structs depend on iOS SDK)

384

interface CGPoint {

385

x: number;

386

y: number;

387

}

388

389

// Assuming CGPoint is available as StructType

390

const point1 = new CGPoint();

391

point1.x = 10;

392

point1.y = 20;

393

394

const point2 = new CGPoint({ x: 30, y: 40 });

395

396

// Compare structs

397

const areEqual = CGPoint.equals(point1, point2);

398

```

399

400

### Unmanaged References

401

402

Support for unmanaged object references and memory ownership transfer.

403

404

```typescript { .api }

405

declare module interop {

406

/**

407

* A type for propagating an unmanaged object reference

408

* When you use this type, you become partially responsible for keeping the object alive

409

*/

410

interface Unmanaged<T> {

411

/**

412

* Get the value as a managed reference and consume an unbalanced retain

413

* Use when a function returns unmanaged reference and you're responsible for releasing

414

* @returns Managed reference to the object

415

*/

416

takeRetainedValue(): T;

417

418

/**

419

* Get the value as a managed reference without consuming an unbalanced retain

420

* Use when a function returns unmanaged reference and you're not responsible for releasing

421

* @returns Managed reference to the object

422

*/

423

takeUnretainedValue(): T;

424

}

425

}

426

```

427

428

**Usage Examples:**

429

430

```typescript

431

// Handle unmanaged references (typically from native functions)

432

declare function getNativeObjectUnmanaged(): interop.Unmanaged<NSString>;

433

434

// Take ownership of returned object

435

const managedString = getNativeObjectUnmanaged().takeRetainedValue();

436

// You are now responsible for this object

437

438

// Or get without taking ownership

439

const borrowedString = getNativeObjectUnmanaged().takeUnretainedValue();

440

// Someone else manages this object

441

```

442

443

### Error Handling

444

445

Native error handling integration with NSError.

446

447

```typescript { .api }

448

declare module interop {

449

interface NSErrorWrapper extends Error {

450

/** The wrapped NSError instance */

451

error: NSError;

452

}

453

454

var NSErrorWrapper: {

455

new(error: NSError): NSErrorWrapper;

456

(error: NSError): NSErrorWrapper;

457

prototype: NSErrorWrapper;

458

}

459

}

460

```

461

462

**Usage Examples:**

463

464

```typescript

465

// Handle NSError in JavaScript

466

try {

467

// Some operation that might produce NSError

468

const result = someNativeOperationThatMightFail();

469

} catch (error) {

470

if (error instanceof interop.NSErrorWrapper) {

471

const nsError = error.error;

472

console.log(`Native error: ${nsError.localizedDescription}`);

473

console.log(`Error code: ${nsError.code}`);

474

}

475

}

476

477

// Create NSErrorWrapper from NSError

478

const nsError = NSError.errorWithDomainCodeUserInfo("MyDomain", 100, null);

479

const wrapper = new interop.NSErrorWrapper(nsError);

480

```

481

482

## Advanced Usage Patterns

483

484

### Memory Management Best Practices

485

486

```typescript

487

// Use adopted pointers for automatic cleanup

488

const buffer = interop.alloc(1024); // Automatically freed

489

490

// Manual management when needed

491

const rawPtr = new interop.Pointer(0x1000);

492

try {

493

// Use rawPtr...

494

} finally {

495

interop.free(rawPtr);

496

}

497

498

// Reference management

499

const objRef = new interop.Reference<NSString>();

500

someNativeFunctionThatSetsRef(objRef);

501

// objRef.value now contains the result

502

```

503

504

### Type Conversion Patterns

505

506

```typescript

507

// Converting between JavaScript and native types

508

const jsNumber = 42;

509

const nativeInt = new interop.Reference(interop.types.int32, jsNumber);

510

511

// Working with C strings

512

const jsString = "Hello World";

513

const cString = NSString.stringWithString(jsString).UTF8String;

514

515

// Buffer operations

516

const nsData = NSData.dataWithContentsOfFile("/path/to/file");

517

const buffer = interop.bufferFromData(nsData);

518

const uint8Array = new Uint8Array(buffer);

519

```