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
```