or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

c-interop.mdcollections.mdconfig.mdindex.mdjni-utils.mdnative-bridge.mdnative-image.mdpolyglot.mdsubstitutions.mdword.md

c-interop.mddocs/

0

# C Interoperability

1

2

Low-level APIs for C function calls, data type interoperability, and native code integration in GraalVM native images.

3

4

## Capabilities

5

6

### C Function Pointers

7

8

Type-safe interfaces for calling C functions from native images with proper argument and return type handling.

9

10

```java { .api }

11

/**

12

* Base interface for C function pointers

13

*/

14

public interface CFunctionPointer extends CodePointer, RelocatedPointer {

15

}

16

17

/**

18

* Pointer to executable code

19

*/

20

public interface CodePointer extends PointerBase {

21

/** Check if code pointer is null */

22

boolean isNull();

23

24

/** Check if code pointer is not null */

25

boolean isNonNull();

26

}

27

28

/**

29

* Relocated function pointer for dynamic linking

30

*/

31

public interface RelocatedPointer extends ComparableWord {

32

/** Check if relocation is resolved */

33

boolean isResolved();

34

35

/** Get raw address if resolved */

36

long getAddress();

37

}

38

```

39

40

**Usage Examples:**

41

42

```java

43

import org.graalvm.nativeimage.c.function.*;

44

45

public class CFunctionExample {

46

// Define C function signature

47

public interface MallocFunction extends CFunctionPointer {

48

@CFunction("malloc")

49

Pointer call(UnsignedWord size);

50

}

51

52

public interface FreeFunction extends CFunctionPointer {

53

@CFunction("free")

54

void call(Pointer ptr);

55

}

56

57

public void useCFunctions() {

58

// Get function pointers

59

MallocFunction malloc = CLibrary.getFunction("malloc", MallocFunction.class);

60

FreeFunction free = CLibrary.getFunction("free", FreeFunction.class);

61

62

// Allocate memory

63

UnsignedWord size = WordFactory.unsigned(1024);

64

Pointer memory = malloc.call(size);

65

66

if (memory.isNonNull()) {

67

// Use memory...

68

memory.writeInt(WordFactory.unsigned(0), 42);

69

70

// Free memory

71

free.call(memory);

72

}

73

}

74

}

75

```

76

77

### C Primitive Pointers

78

79

Typed pointers for accessing C primitive arrays and data structures.

80

81

```java { .api }

82

/**

83

* Pointer to C char array (byte array)

84

*/

85

public interface CCharPointer extends PointerBase {

86

/** Read char at pointer location */

87

byte read();

88

89

/** Read char at given index */

90

byte read(int index);

91

92

/** Write char at pointer location */

93

void write(byte value);

94

95

/** Write char at given index */

96

void write(int index, byte value);

97

98

/** Get pointer to element at index */

99

CCharPointer addressOf(int index);

100

101

/** Check if pointer is null */

102

boolean isNull();

103

}

104

105

/**

106

* Pointer to C int array

107

*/

108

public interface CIntPointer extends PointerBase {

109

/** Read int at pointer location */

110

int read();

111

112

/** Read int at given index */

113

int read(int index);

114

115

/** Write int at pointer location */

116

void write(int value);

117

118

/** Write int at given index */

119

void write(int index, int value);

120

121

/** Get pointer to element at index */

122

CIntPointer addressOf(int index);

123

}

124

125

/**

126

* Pointer to C long array

127

*/

128

public interface CLongPointer extends PointerBase {

129

/** Read long at pointer location */

130

long read();

131

132

/** Read long at given index */

133

long read(int index);

134

135

/** Write long at pointer location */

136

void write(long value);

137

138

/** Write long at given index */

139

void write(int index, long value);

140

141

/** Get pointer to element at index */

142

CLongPointer addressOf(int index);

143

}

144

145

/**

146

* Pointer to C short array

147

*/

148

public interface CShortPointer extends PointerBase {

149

/** Read short at pointer location */

150

short read();

151

152

/** Read short at given index */

153

short read(int index);

154

155

/** Write short at pointer location */

156

void write(short value);

157

158

/** Write short at given index */

159

void write(int index, short value);

160

161

/** Get pointer to element at index */

162

CShortPointer addressOf(int index);

163

}

164

165

/**

166

* Pointer to C float array

167

*/

168

public interface CFloatPointer extends PointerBase {

169

/** Read float at pointer location */

170

float read();

171

172

/** Read float at given index */

173

float read(int index);

174

175

/** Write float at pointer location */

176

void write(float value);

177

178

/** Write float at given index */

179

void write(int index, float value);

180

181

/** Get pointer to element at index */

182

CFloatPointer addressOf(int index);

183

}

184

185

/**

186

* Pointer to C double array

187

*/

188

public interface CDoublePointer extends PointerBase {

189

/** Read double at pointer location */

190

double read();

191

192

/** Read double at given index */

193

double read(int index);

194

195

/** Write double at pointer location */

196

void write(double value);

197

198

/** Write double at given index */

199

void write(int index, double value);

200

201

/** Get pointer to element at index */

202

CDoublePointer addressOf(int index);

203

}

204

```

205

206

**Usage Examples:**

207

208

```java

209

public class CPrimitiveArrays {

210

public void workWithArrays() {

211

// Allocate C int array

212

CIntPointer intArray = allocateIntArray(10);

213

214

// Write values

215

for (int i = 0; i < 10; i++) {

216

intArray.write(i, i * i); // Store squares

217

}

218

219

// Read values

220

for (int i = 0; i < 10; i++) {

221

int value = intArray.read(i);

222

System.out.println("intArray[" + i + "] = " + value);

223

}

224

225

// Pointer arithmetic

226

CIntPointer fifthElement = intArray.addressOf(5);

227

int value = fifthElement.read(); // Same as intArray.read(5)

228

229

// Work with char array (C string)

230

CCharPointer cString = allocateCharArray(256);

231

byte[] javaString = "Hello, C!".getBytes();

232

233

for (int i = 0; i < javaString.length; i++) {

234

cString.write(i, javaString[i]);

235

}

236

cString.write(javaString.length, (byte) 0); // Null terminator

237

238

// Free memory

239

free(intArray);

240

free(cString);

241

}

242

243

// Placeholder allocation methods

244

private native CIntPointer allocateIntArray(int size);

245

private native CCharPointer allocateCharArray(int size);

246

private native void free(PointerBase ptr);

247

}

248

```

249

250

### Pointer-to-Pointer Types

251

252

Double indirection pointers for working with C arrays of pointers and complex data structures.

253

254

```java { .api }

255

/**

256

* Pointer to array of char pointers (array of C strings)

257

*/

258

public interface CCharPointerPointer extends PointerBase {

259

/** Read char pointer at location */

260

CCharPointer read();

261

262

/** Read char pointer at given index */

263

CCharPointer read(int index);

264

265

/** Write char pointer at location */

266

void write(CCharPointer value);

267

268

/** Write char pointer at given index */

269

void write(int index, CCharPointer value);

270

271

/** Get pointer to element at index */

272

CCharPointerPointer addressOf(int index);

273

}

274

275

/**

276

* Pointer to array of int pointers

277

*/

278

public interface CIntPointerPointer extends PointerBase {

279

/** Read int pointer at location */

280

CIntPointer read();

281

282

/** Read int pointer at given index */

283

CIntPointer read(int index);

284

285

/** Write int pointer at location */

286

void write(CIntPointer value);

287

288

/** Write int pointer at given index */

289

void write(int index, CIntPointer value);

290

291

/** Get pointer to element at index */

292

CIntPointerPointer addressOf(int index);

293

}

294

```

295

296

**Usage Examples:**

297

298

```java

299

public class PointerToPointerExample {

300

public void workWithStringArray() {

301

// Create array of C strings (char**)

302

String[] javaStrings = {"Hello", "World", "from", "Java"};

303

CCharPointerPointer stringArray = allocateStringArray(javaStrings.length);

304

305

// Convert Java strings to C strings

306

for (int i = 0; i < javaStrings.length; i++) {

307

CCharPointer cString = createCString(javaStrings[i]);

308

stringArray.write(i, cString);

309

}

310

311

// Read back C strings

312

for (int i = 0; i < javaStrings.length; i++) {

313

CCharPointer cString = stringArray.read(i);

314

String javaString = readCString(cString);

315

System.out.println("String[" + i + "] = " + javaString);

316

}

317

318

// Free memory

319

for (int i = 0; i < javaStrings.length; i++) {

320

free(stringArray.read(i));

321

}

322

free(stringArray);

323

}

324

325

// Helper methods

326

private CCharPointer createCString(String javaString) {

327

byte[] bytes = javaString.getBytes();

328

CCharPointer cString = allocateCharArray(bytes.length + 1);

329

330

for (int i = 0; i < bytes.length; i++) {

331

cString.write(i, bytes[i]);

332

}

333

cString.write(bytes.length, (byte) 0); // Null terminator

334

335

return cString;

336

}

337

338

private String readCString(CCharPointer cString) {

339

// Find length

340

int length = 0;

341

while (cString.read(length) != 0) {

342

length++;

343

}

344

345

// Convert to Java string

346

byte[] bytes = new byte[length];

347

for (int i = 0; i < length; i++) {

348

bytes[i] = cString.read(i);

349

}

350

return new String(bytes);

351

}

352

353

// Placeholder methods

354

private native CCharPointerPointer allocateStringArray(int size);

355

private native CCharPointer allocateCharArray(int size);

356

private native void free(PointerBase ptr);

357

}

358

```

359

360

### Generic Pointers

361

362

Generic pointer types for untyped memory access and void pointer equivalents.

363

364

```java { .api }

365

/**

366

* Generic void pointer equivalent

367

*/

368

public interface VoidPointer extends PointerBase {

369

/** Cast to typed pointer */

370

<T extends PointerBase> T cast(Class<T> targetType);

371

372

/** Get raw memory address */

373

long getAddress();

374

375

/** Create from raw address */

376

static VoidPointer fromAddress(long address);

377

}

378

379

/**

380

* Pointer sized to hold a machine word

381

*/

382

public interface WordPointer extends PointerBase {

383

/** Read word value at pointer location */

384

UnsignedWord read();

385

386

/** Read word value at given index */

387

UnsignedWord read(int index);

388

389

/** Write word value at pointer location */

390

void write(UnsignedWord value);

391

392

/** Write word value at given index */

393

void write(int index, UnsignedWord value);

394

395

/** Get pointer to element at index */

396

WordPointer addressOf(int index);

397

}

398

```

399

400

**Usage Examples:**

401

402

```java

403

public class GenericPointers {

404

public void useGenericPointers() {

405

// Allocate generic memory

406

VoidPointer memory = allocateMemory(1024);

407

408

// Cast to specific types as needed

409

CIntPointer intPtr = memory.cast(CIntPointer.class);

410

intPtr.write(0, 42);

411

412

CFloatPointer floatPtr = memory.cast(CFloatPointer.class);

413

floatPtr.write(1, 3.14f);

414

415

// Work with word-sized values

416

WordPointer wordPtr = memory.cast(WordPointer.class);

417

wordPtr.write(2, WordFactory.unsigned(0xDEADBEEF));

418

419

// Read back values

420

System.out.println("Int: " + intPtr.read(0));

421

System.out.println("Float: " + floatPtr.read(1));

422

System.out.println("Word: " + wordPtr.read(2).rawValue());

423

424

// Get raw address for external APIs

425

long address = memory.getAddress();

426

System.out.println("Memory address: 0x" + Long.toHexString(address));

427

428

free(memory);

429

}

430

431

// Placeholder methods

432

private native VoidPointer allocateMemory(int size);

433

private native void free(VoidPointer ptr);

434

}

435

```

436

437

### C Structure Support

438

439

Support for defining and accessing C structures through Java interfaces.

440

441

```java { .api }

442

/**

443

* Base interface for C structure types

444

*/

445

public interface CStruct extends PointerBase {

446

/** Get size of structure in bytes */

447

UnsignedWord sizeof();

448

449

/** Get address of structure */

450

Pointer getAddress();

451

}

452

453

/**

454

* Support for C unions

455

*/

456

public interface CUnion extends PointerBase {

457

/** Get size of union in bytes */

458

UnsignedWord sizeof();

459

460

/** Get address of union */

461

Pointer getAddress();

462

}

463

```

464

465

**Usage Examples:**

466

467

```java

468

// Define C structure interface

469

public interface Point extends CStruct {

470

@CField("x")

471

int getX();

472

473

@CField("x")

474

void setX(int value);

475

476

@CField("y")

477

int getY();

478

479

@CField("y")

480

void setY(int value);

481

}

482

483

public class StructureExample {

484

public void useStructures() {

485

// Allocate structure

486

Point point = allocatePoint();

487

488

// Set values

489

point.setX(10);

490

point.setY(20);

491

492

// Read values

493

System.out.println("Point: (" + point.getX() + ", " + point.getY() + ")");

494

495

// Pass to C function

496

double distance = calculateDistance(point);

497

System.out.println("Distance from origin: " + distance);

498

499

free(point);

500

}

501

502

// Placeholder methods

503

private native Point allocatePoint();

504

private native double calculateDistance(Point point);

505

private native void free(CStruct struct);

506

}

507

```

508

509

## Types

510

511

```java { .api }

512

// Annotations for C interoperability (from substitutions module)

513

@Target(ElementType.METHOD)

514

@Retention(RetentionPolicy.RUNTIME)

515

public @interface CFunction {

516

/** C function name to bind to */

517

String value() default "";

518

519

/** Library containing the function */

520

String library() default "";

521

}

522

523

@Target(ElementType.METHOD)

524

@Retention(RetentionPolicy.RUNTIME)

525

public @interface CField {

526

/** C field name to bind to */

527

String value();

528

529

/** Offset within structure */

530

int offset() default -1;

531

}

532

533

@Target(ElementType.TYPE)

534

@Retention(RetentionPolicy.RUNTIME)

535

public @interface CStruct {

536

/** C structure name */

537

String value() default "";

538

539

/** Add padding for alignment */

540

boolean addStructKeyword() default false;

541

}

542

543

// Exception types

544

public class CInterfaceException extends RuntimeException {

545

public CInterfaceException(String message);

546

public CInterfaceException(String message, Throwable cause);

547

}

548

549

// Utility classes

550

public final class CTypeConversion {

551

/** Convert Java string to C string */

552

public static CCharPointer toCString(String javaString);

553

554

/** Convert C string to Java string */

555

public static String toJavaString(CCharPointer cString);

556

557

/** Convert Java byte array to C char array */

558

public static CCharPointer toCBytes(byte[] javaBytes);

559

560

/** Convert C char array to Java byte array */

561

public static byte[] toJavaBytes(CCharPointer cBytes, int length);

562

}

563

```