TYPED CONVERSIONS
Give your C project a header and a separately compiled source file for each Python module, together with an exact interface manifest.
Mode: Typed conversion. This export uses the current Typed conversion result. Runtime conversion continues to use single-file output. Exporting does not compile or execute your source.
.zip destination in the themed file chooser..c file separately.The command is disabled until a fresh Typed conversion is available. Source and identity edits retire export access immediately. If the workspace changes while an archive is being prepared, it is not published and an existing destination stays intact.
Save C still saves the single-file result. The Generated C viewer, ForgeLens, and the IDE Compile action continue to use that result. Module exports do not change its destination.
| File | Purpose |
|---|---|
One pcf_….h per module | Exact declarations for its exported source functions. |
One pcf_….c per module | Its converted function bodies and the internal helpers they need. |
pycforge_types.h | Shared C includes and any generated record declarations. |
pycforge_abi.json | Module/file mapping, function symbols, complete C parameter declarations, record field layouts, ownership, dependencies and source/header hashes. |
BUILD.txt | Separate compilation and linking instructions. |
Filenames use a digest of the module identity plus a readable suffix. Use the manifest to identify each header and source. All source functions are exported; support helpers retain internal linkage. A function beginning with an underscore is not automatically hidden.
Keep the module identity main for this example.
def square(value: int) -> int:
return value * value
The same export can be created through the Python API. Run this script in a directory where you want to save the archive.
from pathlib import Path
from pycforge import ConversionRequest, PythonToCConverter, export_c_modules
source = "def square(value: int) -> int:\n return value * value\n"
result = PythonToCConverter().convert(ConversionRequest.from_source(source))
if result.generated_c is None:
raise RuntimeError("Conversion failed; inspect result.diagnostics")
exported = export_c_modules(result)
Path("c-modules.zip").write_bytes(exported.zip_bytes())
Extract c-modules.zip, then save this separate caller as caller.c beside the exported files.
#include <inttypes.h>
#include <stdio.h>
#include "pcf_0d6e4079e36703eb_main.h"
int main(void)
{
printf("%" PRId64 "\n", square(12));
return 0;
}
For GCC or Clang, compile the generated source to an object, then link it with your caller:
gcc -std=c11 -c pcf_0d6e4079e36703eb_main.c -o square.o gcc -std=c11 caller.c square.o -o square-demo
Run ./square-demo on Linux/macOS or .\square-demo.exe in Windows PowerShell. It prints 144. For a larger bundle compile every generated .c once and link all the objects. Include -lm where your toolchain requires it for math helpers.
A supported record parameter or return becomes a struct value in the exported function declaration. The module header includes pycforge_types.h, so the caller sees the complete layout. The manifest's record_types lists the generated struct and field names and their exact C types.
For this standalone example, keep the module identity main. Transpile and export it in a separate directory from the square example.
class Point:
x: int
y: int
def __init__(self, x: int, y: int) -> None:
self.x = x
self.y = y
def make_point(x: int, y: int) -> Point:
return Point(x, y)
def sum_point(point: Point) -> int:
return point.x + point.y
Save the following as caller.c beside this example's exported files. Compile and link using the commands above. It prints 7.
#include <inttypes.h>
#include <stdio.h>
#include "pcf_0d6e4079e36703eb_main.h"
int main(void)
{
Point point = make_point(3, 4);
printf("%" PRId64 "\n", sum_point(point));
return 0;
}
The returned struct owns its inline scalar values. Passing it copies those values; no allocation, disposal call, or free is required. If you construct a struct in C, initialize every field with a value valid for the corresponding typed field. Keep the generated declarations intact and use the manifest's names for your own source bundle.
Direct Python imports can share a record type across supplied modules. The shared type header contains one complete struct layout for each declaring class; aliases use the same type. A record-only module has a source/header pair with no exported functions. See the multi-module geometry example. Function-call dependencies remain listed per module; record layouts are available through the shared type header.
generated_name and c_declaration from the manifest. Multi-module functions have module-qualified generated symbols; do not guess names from Python identifiers.int64_t * status argument. Check it before using a return value; free a successful owned read buffer exactly once. See file caller contracts.