{"id":46300,"date":"2026-01-01T09:11:00","date_gmt":"2026-01-01T09:11:00","guid":{"rendered":"https:\/\/foojay.io\/?p=46300"},"modified":"2026-01-22T00:11:06","modified_gmt":"2026-01-22T00:11:06","slug":"project-panama-for-newbies-part-1","status":"publish","type":"post","link":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/","title":{"rendered":"Project Panama for Newbies (Part 1)"},"content":{"rendered":"\n    <div class=\"article__table\">\n        <div class=\"article__table-header\">\n            <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                <path d=\"M8 6H21\" stroke=\"#3562E5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                <path d=\"M8 12H21\" stroke=\"#3562E5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                <path d=\"M8 18H21\" stroke=\"#3562E5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                <path d=\"M3 6H3.01\" stroke=\"#3562E5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                <path d=\"M3 12H3.01\" stroke=\"#3562E5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n                <path d=\"M3 18H3.01\" stroke=\"#3562E5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" \/>\n            <\/svg>\n            Table of Contents\n            <svg class=\"chevron\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                <path d=\"M18 15L12 9L6 15\" stroke=\"#3562E5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\n            <\/svg>\n        <\/div>\n        <div class=\"article__table-body\"><span><a href=\"#h2-0--hat-is-roject-anama-\">What is Project Panama?<\/a><\/span><span><a href=\"#h2-1--hy-se-roject-anama-\">Why Use Project Panama?<\/a><\/span><span><a href=\"#h2-2--here-do-get-the-jextract-tool-\">Where do I get the jextract tool?<\/a><\/span><span><a href=\"#h2-3--o-need-a-compiler-\">Do I need a C compiler?<\/a><\/span><span><a href=\"#h2-4--et-s-o-t-\">Let\u2019s Do It!<\/a><\/span><span><a href=\"#h2-5--natomy-of-a-ello-orld-in-\">Anatomy of a Hello World in C<\/a><\/span><span><a href=\"#h2-6--anama-ello-orld-xample\">Panama Hello World Example<\/a><\/span><span><a href=\"#h2-7--et-s-jextract-please-\">Let\u2019s jextract STDIO please!<\/a><\/span><span><a href=\"#h2-8--ow-does-it-work-\">How does it work?<\/a><\/span><ul><li><a href=\"#h3-9--hat-about-3rd-party-libraries-\">What about 3rd party C libraries?<\/a><\/li><li><a href=\"#h3-10--reating-etting-etting-primitive-data-types-from-ava\">Creating\/Getting\/Setting C primitive data types from Java<\/a><\/li><li><a href=\"#h3-11--reating-primitive-arrays\">Creating C primitive arrays<\/a><\/li><\/ul><\/div><\/div><!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD HTML 4.0 Transitional\/\/EN\" \"http:\/\/www.w3.org\/TR\/REC-html40\/loose.dtd\">\n<?xml encoding=\"utf-8\" ?><html><body><p><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">Updated<\/mark> December 28, 2025 (<strong>originally published August 10<\/strong>, 2021, republished January 1, 2026):<\/strong>&nbsp;This article now features Java 25 and the Foreign Function &amp; Memory (FFM) API, which has been a standard feature since JDK 22.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"226\" height=\"407\" src=\"https:\/\/foojay.io\/wp-content\/uploads\/2021\/08\/duke_and_panama.png\" alt=\"Java's Project Panama\" class=\"wp-image-46303\"><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">Introduction<\/h1>\n\n\n\n<p>In this series of articles, we will explore the APIs from OpenJDK&rsquo;s <a href=\"https:\/\/openjdk.java.net\/projects\/panama\/\" target=\"_blank\" rel=\"noreferrer noopener\">Project<\/a> <a href=\"http:\/\/jdk.java.net\/panama\/\" target=\"_blank\" rel=\"noreferrer noopener\">Panama<\/a>. My intent is to show you how to be proficient in using the Foreign Function and Memory Access APIs as it relates to Java interoperability with native code.  After FFI (foreign function interface) &amp; FFM (foreign function memory)  have been finalized in JDK 22 the APIs currently reside in the following package namespaces.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">java.lang.invoke.*;\njava.lang.foreign.*;\n<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>While this article is for newbies, I assume you know the basics of the Java language, a little bash scripting, and a familiarity with C programming concepts. If you are new to C language don&rsquo;t worry I will go over the concepts later.<\/p>\n\n\n\n<p>For the impatient go to <a href=\"https:\/\/github.com\/carldea\/panama4newbies\" target=\"_blank\" rel=\"noreferrer noopener\">Panama4Newbies<\/a> on GitHub. <\/p>\n\n\n\n<p>In Part 1 of this series, I will give you an overview of the requirements and later go through some exercises as a primer to create memory outside of Java's heap and call into native C functions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h2-0--hat-is-roject-anama-\">What is Project Panama?<\/h2>\n\n\n\n<p>Project Panama is a new way for the Java programming language to access native libraries that are written in native languages like C, C++, Objective-C\/C++, Swift, Rust and Python (currently supports the C <a target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Application_binary_interface\">ABI<\/a>). While my description might be an oversimplification, Project Panama has been in the making for quite some time (11+ years) and continues to have great success! Kudos and a huge shout out to the OpenJDK community at large!<\/p>\n\n\n\n<p>Project Panama is an umbrella project that comprises many JEPs (Java Enhancement Proposal) as shown below:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Foreign Function and Memory Access APIs\n<ul class=\"wp-block-list\">\n<li>1st Incubator <a href=\"https:\/\/openjdk.java.net\/jeps\/412\" target=\"_blank\" rel=\"noreferrer noopener\">JEP-412<\/a><\/li>\n\n\n\n<li>2nd Incubator <a href=\"https:\/\/openjdk.java.net\/jeps\/419\" target=\"_blank\" rel=\"noreferrer noopener\">JEP-419<\/a><\/li>\n\n\n\n<li>Preview <a target=\"_blank\" href=\"https:\/\/openjdk.java.net\/jeps\/424\">JEP-424<\/a><\/li>\n\n\n\n<li>Final <a target=\"_blank\" href=\"https:\/\/openjdk.java.net\/jeps\/454\">JEP-454<\/a> released in Java 22<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Foreign-Memory Access API - is a way to allocate and map memory outside of the JVM&rsquo;s heap. Capable of creating C pointers, structs, and other primitive or native data types: <a target=\"_blank\" title=\"JEP-370\" href=\"https:\/\/openjdk.java.net\/jeps\/370\">JEP-370<\/a>,&nbsp;<a target=\"_blank\" title=\"JEP-383\" href=\"https:\/\/openjdk.java.net\/jeps\/383\">JEP-383<\/a><\/li>\n\n\n\n<li>Foreign Linker API - is a way to access functions in native libraries:&nbsp;<a target=\"_blank\" title=\"JEP-389\" href=\"https:\/\/openjdk.java.net\/jeps\/389\">JEP-389<\/a><\/li>\n\n\n\n<li>Vector API - a platform agnostic way to utilize vector hardware such as SIMD (Single Instruction Multiple Data) chips. \n<ul class=\"wp-block-list\">\n<li><a target=\"_blank\" title=\"JEP-338\" href=\"https:\/\/openjdk.java.net\/jeps\/338\">JEP-338<\/a> 1st (JDK 16)<\/li>\n\n\n\n<li><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/414\">JEP&nbsp;414<\/a>&nbsp; 2nd (JDK 17)<\/li>\n\n\n\n<li><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/417\">JEP&nbsp;417<\/a>&nbsp; 3rd (JDK&nbsp;18)<\/li>\n\n\n\n<li><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/426\">JEP&nbsp;426<\/a>&nbsp;4th (JDK&nbsp;19)<\/li>\n\n\n\n<li><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/438\">JEP&nbsp;438<\/a>&nbsp;5th (JDK&nbsp;20)<\/li>\n\n\n\n<li><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/448\">JEP&nbsp;448<\/a> 6th (JDK&nbsp;21)<\/li>\n\n\n\n<li><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/460\">JEP&nbsp;460<\/a>&nbsp;7th (JDK&nbsp;22)<\/li>\n\n\n\n<li><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/469\">JEP&nbsp;469<\/a>&nbsp;8th (JDK&nbsp;23)<\/li>\n\n\n\n<li><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/489\">JEP&nbsp;489<\/a>&nbsp;9th (JDK&nbsp;24)<\/li>\n\n\n\n<li><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/508\">JEP&nbsp;508<\/a>&nbsp;10th (JDK&nbsp;25)<\/li>\n\n\n\n<li><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/529\">JEP 529<\/a> 11th incubator (JDK 26)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><strong>Note:<\/strong> \"Project Panama for Newbies (articles)\" will defer coverage of the Vector API until it moves past the incubation stage. Currently in its 11th incubation and slated for JDK 26, the API is undergoing significant alignment with Project Valhalla under&nbsp;<br><a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/529\">JEP 529<\/a>. These efforts focus on leveraging value types and enhancing auto-vectorization for hardware targets, with the ultimate goal of reducing memory overhead and boosting performance.<\/p>\n\n\n\n<p>Shown below is the timeline of the roadmap:<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"349\" data-id=\"52487\" src=\"https:\/\/foojay.io\/wp-content\/uploads\/2022\/02\/timeline_panama-1024x349.png\" alt=\"\" class=\"wp-image-52487\" srcset=\"https:\/\/foojay.io\/wp-content\/uploads\/2022\/02\/timeline_panama-1024x349.png 1024w, https:\/\/foojay.io\/wp-content\/uploads\/2022\/02\/timeline_panama-700x238.png 700w, https:\/\/foojay.io\/wp-content\/uploads\/2022\/02\/timeline_panama-768x261.png 768w, https:\/\/foojay.io\/wp-content\/uploads\/2022\/02\/timeline_panama.png 1501w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/figure>\n\n\n\n<p><strong>Note:<\/strong> The infographic above is missing the following Java Enhancement proposals:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>JEP-424 (2022-02 to 2025-09)<\/li>\n\n\n\n<li>JEP-454 (2023-06 to 2024-10)<\/li>\n<\/ul>\n\n\n\n<p>The tutorial series is based on <strong>JEP 454<\/strong> (final was released in JDK 22).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h2-1--hy-se-roject-anama-\">Why Use Project Panama?<\/h2>\n\n\n\n<p>Before answering why, let me ask another question, Have you heard of Minecraft? If you answered \"Yes, of course\", then, great! If you answered \"No\", then please go and visit <a target=\"_blank\" href=\"https:\/\/www.minecraft.net\/en-us\"><\/a><a target=\"_blank\" href=\"https:\/\/www.minecraft.net\/en-us\">https:\/\/www.minecraft.net\/en-us<\/a>. Did you also know that Minecraft is written in Java using the popular open source gaming library called <a target=\"_blank\" title=\"LWJGL\" href=\"https:\/\/www.lwjgl.org\/\">LWJGL<\/a> (LightWeight Java Game Library)?<\/p>\n\n\n\n<p>So, where am I going with this? As you dig deeper into the gaming library&rsquo;s <a target=\"_blank\" title=\"implementation\" href=\"https:\/\/github.com\/LWJGL\/lwjgl3\/blob\/master\/config\/macos\/build.xml\">implementation<\/a> you&rsquo;ll discover that it uses <a target=\"_blank\" title=\"JNI\" href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/technotes\/guides\/jni\/\">JNI<\/a> (Java Native Interface) to access native libraries such as OpenGL, OpenCL, etc. These native libraries are written in C (language) capable of accessing hardware on a device such as sound, input devices, or GPUs.<\/p>\n\n\n\n<p>So, back to the answer to \"Why?\". The short answer is: Panama is simpler to use and can have better performance.<\/p>\n\n\n\n<p>The longer answer is that using JNI's generated code and wrapper code can be error prone, and is often difficult to maintain over time. Also, it requires natively compiled glue (wrapper) code to be installed on the system (which means you&rsquo;ll need system administrative privileges). In other words, project Panama is a pure Java solution that allows you to access existing native libraries with comparable or better performance than JNI.<\/p>\n\n\n\n<p>Here are the use cases for using Project Panama:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Access C\/C++ code from Java<\/li>\n\n\n\n<li>Access device drivers on embedded environments such as Raspberry Pi<\/li>\n\n\n\n<li>Access memory off the JVM&rsquo;s heap (Safely). Replace the use of Unsafe API. <\/li>\n\n\n\n<li>Increased performance using lower level APIs to access SIMD hardware.<\/li>\n\n\n\n<li>Up calls or Callbacks from C code to Java code<\/li>\n<\/ul>\n\n\n\n<p>Okay, so now that you are convinced, how to get started?<\/p>\n\n\n\n<p>Before we begin, it is important to understand&nbsp;<strong>jextract<\/strong>, a command-line tool that automates the generation of the low-level&nbsp;Project Panama&nbsp;Java code. By binding native libraries to Java, jextract eliminates the tedious manual work required to invoke native functions and interact with native symbols.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h2-2--here-do-get-the-jextract-tool-\">Where do I get the jextract tool?<\/h2>\n\n\n\n<p>To acquire&nbsp;<strong>jextract<\/strong>, you can either build it from source or download a pre-compiled version:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Build from source:<\/strong>&nbsp;Clone the official&nbsp;<a href=\"https:\/\/github.com\/openjdk\/jextract\" target=\"_blank\" rel=\"noreferrer noopener\">jextract repository<\/a>&nbsp;on GitHub and follow the build instructions provided in the README.<\/li>\n\n\n\n<li><strong>Download pre-built releases:<\/strong>&nbsp;For a more convenient setup, download the latest early-access binaries for your operating system (Windows, macOS, or Linux) directly from&nbsp;<a href=\"https:\/\/jdk.java.net\/jextract\/\" target=\"_blank\" rel=\"noreferrer noopener\">jdk.java.net\/jextract<\/a>.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>As we explore further, we will learn that the <code>jextract<\/code> tool is responsible for generating Java (code) bindings derived from C header files (<code>.h<\/code>) and their associated native library files. Library files with the extension <code>.dll<\/code>, <code>.so<\/code> and <code>.dylib<\/code> are used on the Windows, Linux, and MacOS operating systems respectively.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting Started<\/h1>\n\n\n\n<p>Let us make sure your environment is setup before we begin. The following are the install instructions for your respective OS.<\/p>\n\n\n\n<p><strong>Mac OS X \/ Linux setup instructions:<\/strong><br><br><strong>Step 1<\/strong>: Download JDK 25+ from <a href=\"https:\/\/azul.com\/downloads\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a><a target=\"_blank\" href=\"https:\/\/azul.com\/downloads\">https:\/\/azul.com\/downloads<\/a> and untar or unzip into a directory.<\/p>\n\n\n\n<p><code>$ export <span style=\"font-family: inherit; font-size: inherit; text-align: initial;\">JAVA_HOME<\/span>=&lt;path to JDK&gt;<\/code><\/p>\n\n\n\n<p><strong>Step 2<\/strong>: Download the latest release of <code>jextract<\/code> <a href=\"https:\/\/jdk.java.net\/jextract\/\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a> . After download unzip into a directory. Next setup your <code>JEXTRACT_HOME<\/code> environment variable.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ export <span style=\"font-family: inherit; font-size: inherit; text-align: initial;\">JEXTRACT_HOME<\/span>=&lt;path to jextract&gt;<\/code><\/pre>\n\n\n\n<p><strong>Step 3<\/strong>: Set <code>PATH<\/code><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> # Mac\/Linux\n $ export JAVA_HOME=&lt;path to JDK&gt;\n $ export JEXTRACT_HOME=&lt;path to jextract&gt;\n $ export PATH=$JAVA_HOME\/bin:JEXTRACT_HOME\/bin:$PATH<\/pre>\n\n\n\n<p><strong>Note:<\/strong> To make environment variables permanent you can set these in your <code>.bashrc<\/code> or <code>.bash_profile<\/code> files on Linux or MacOS respectively. On newer Macs you can set them in your <code>.zshrc<\/code> or <code>.zprofile<\/code> <\/p>\n\n\n\n<p><strong>Step 4:<\/strong> Test Java runtime and the <code>jextract<\/code> tool are available<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> $ java -version\n $ jextract -h<\/pre>\n\n\n\n<p><strong>Windows instructions:<\/strong><br><br>Step 1: Download JDK and jextract <a href=\"https:\/\/jdk.java.net\/jextract\/\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>. Next, untar or unzip them into a directory.<br>Step 2: Set <code>JAVA_HOME<\/code>, <code>JEXTRACT_HOME<\/code> and <code>PATH<\/code> environment variables<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> c:\\&gt; set JAVA_HOME=&lt;path to JDK&gt;\n c:\\&gt; set JEXTRACT_HOME=&lt;path to jextract&gt;\n c:\\&gt; set PATH=%JAVA_HOME%\\bin;%JEXTRACT_HOME\/bin%;%PATH%<\/pre>\n\n\n\n<p><strong>Note:<\/strong> To make environment variables permanent on the Windows platform do the following:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Right-click the&nbsp;Computer&nbsp;icon and choose&nbsp;Properties, or in Windows Control Panel, choose&nbsp;System.<\/li>\n\n\n\n<li>Choose&nbsp;Advanced system settings.<\/li>\n\n\n\n<li>Relaunch a command prompt (cmd.exe)<\/li>\n<\/ol>\n\n\n\n<p><strong>Step 3:<\/strong> Test runtime and jextract is available<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> c:\\&gt; java -version\n c:\\&gt; jextract -h<\/pre>\n\n\n\n<p>After running jextract -h to display the switch options you&rsquo;ll know you are ready to go. You should see something like the following:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Usage: jextract &lt;options&gt; &lt;header file&gt; [&lt;header file&gt;] [...]                                   \n\nOption                             Description                                                  \n------                             -----------                                                  \n-?, -h, --help                     print help                                                   \n-D --define-macro &lt;macro&gt;=&lt;value&gt;  define &lt;macro&gt; to &lt;value&gt; (or 1 if &lt;value&gt; omitted)          \n-I, --include-dir &lt;dir&gt;            add directory to the end of the list of include search paths \n--dump-includes &lt;file&gt;             dump included symbols into specified file                    \n--header-class-name &lt;name&gt;         name of the generated header class. If this option is not    \n                                   specified, then header class name is derived from the header\n                                   file name. For example, class \"foo_h\" for header \"foo.h\".   \n--include-function &lt;name&gt;          name of function to include                                  \n--include-constant &lt;name&gt;          name of macro or enum constant to include                    \n--include-struct &lt;name&gt;            name of struct definition to include                         \n--include-typedef &lt;name&gt;           name of type definition to include                           \n--include-union &lt;name&gt;             name of union definition to include                          \n--include-var &lt;name&gt;               name of global variable to include                           \n-l, --library &lt;libspec&gt;            specify a shared library that should be loaded by the        \n                                   generated header class. If &lt;libspec&gt; starts with :, then  \n                                   what follows is interpreted as a library path. Otherwise,   \n                                   &lt;libspec&gt; denotes a library name. Examples:                 \n                                      -l GL                                                    \n                                      -l :libGL.so.1                                           \n                                      -l :\/usr\/lib\/libGL.so.1                                  \n--use-system-load-library          libraries specified using -l are loaded in the loader symbol \n                                   lookup (using either System::loadLibrary, or System::load). \n                                   Useful if the libraries must be loaded from one of the paths\n                                   in java.library.path.                                     \n--output &lt;path&gt;                    specify the directory to place generated files. If this      \n                                   option is not specified, then current directory is used.    \n-t, --target-package &lt;package&gt;     target package name for the generated classes. If this option\n                                   is not specified, then unnamed package is used.             \n--symbols-class-name &lt;name&gt;        override the name of the root header class                   \n--version                          print version information and exit                           \n\nmacOS platform options for running jextract (available only when running on macOS):             \n-F &lt;dir&gt;            specify the framework directory                                     \n--framework &lt;framework&gt;                     specify framework library. --framework libGL is equivalent to         \n                                      -l :\/System\/Library\/Frameworks\/libGL.framework\/libGL\n <\/pre>\n\n\n\n<p>If you are seeing the <code>jextract<\/code> options then you are ready to go to the next section.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h2-3--o-need-a-compiler-\">Do I need a C compiler?<\/h2>\n\n\n\n<p>In short, <strong>No<\/strong>. For demonstration purposes I will be using a standard C compiler on my MacOS environment. This is purely optional and I will use it to show concepts inside a C program.<\/p>\n\n\n\n<p>If you are on a Windows OS you can check out Microsoft&rsquo;s Visual C++ that includes a C compiler (<a target=\"_blank\" href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/walkthrough-compile-a-c-program-on-the-command-line?view=msvc-160\"><\/a><a target=\"_blank\" href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/walkthrough-compile-a-c-program-on-the-command-line?view=msvc-160\">https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/walkthrough-compile-a-c-program-on-the-command-line?view=msvc-160<\/a>). Also, you can download MingW at <a href=\"https:\/\/www.mingw-w64.org\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a><a target=\"_blank\" href=\"https:\/\/www.mingw-w64.org\">https:\/\/www.mingw-w64.org<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h2-4--et-s-o-t-\">Let&rsquo;s Do It!<\/h2>\n\n\n\n<p>Before we get into using Panama&rsquo;s APIs let's begin by looking at a <strong>Hello World<\/strong> example in the C programming language. By understanding what a C program consists of will help us know how to invoke <strong>native<\/strong> code. Later on we will write a pure Hello World Java program that will call into standard C (native) functions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h2-5--natomy-of-a-ello-orld-in-\">Anatomy of a Hello World in C<\/h2>\n\n\n\n<p><strong>Note:<\/strong> Remember, this part of the tutorial is purely <em>optional<\/em> if you don&rsquo;t have a C compiler handy for your OS just skip the compilation step.<\/p>\n\n\n\n<p><strong>Step 1:<\/strong> Enter the listing 1 into an editor and save the file as helloworld.c.<\/p>\n\n\n\n<p><strong>Listing 1:<\/strong> <code>helloworld.c<\/code><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h&gt;\nint main() {\n   printf(\"Hello, World! \\n\");\n   return 0;\n}<\/pre>\n\n\n\n<p><strong>Step 2:<\/strong> Compile the code<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$ gcc helloworld.c<\/pre>\n\n\n\n<p><strong>Step 3:<\/strong> List the executable file<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$ ls -l a.out\n-rwxr-xr-x  1 jdoe  staff  49424 Jul 29 21:06 a.out<\/pre>\n\n\n\n<p><strong>Step 4:<\/strong> Run or execute the program<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$ .\/a.out\nHello, World!<\/pre>\n\n\n\n<p>Well that was pretty straight forward! Let&rsquo;s unpack what is actually going on. Below is a high-level look at what the C program is doing.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Include statement using Ansi C&rsquo;s <code>stdio.h<\/code> library header. Similar to Java&rsquo;s imports.<\/li>\n\n\n\n<li>The <code>main()<\/code> function is the entry point similar to Java&rsquo;s <code>public static void main()<\/code> method<\/li>\n\n\n\n<li>The <code>main()<\/code> function has a C <code>int<\/code> return type.<\/li>\n\n\n\n<li>The body calls the <code>stdio<\/code>&rsquo;s <code>printf()<\/code> function that takes a <code>const char *<\/code> type.<\/li>\n<\/ul>\n\n\n\n<p>Here are more details on the four observations:<br><br>In <strong>Step 1<\/strong> the <code>stdio<\/code> is C&rsquo;s standard input output library. In the C programming language files with <code>.h<\/code> are similar to Java&rsquo;s interfaces where it defines or describes function signatures and constants of a library. The stdio library in the example contains the <code>printf()<\/code> function equivalent to the <code>System.out.printf()<\/code> in a Java program.<\/p>\n\n\n\n<p>In <strong>Step 2<\/strong> the C programming language it has two overloaded functions of <code>main()<\/code>. One takes an empty parameter signiture, and the other will take number of args (type int) and an array of type <code>char *<\/code> (C string).<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main() {}\nint main(int argc, char *argv[]) {}<\/pre>\n\n\n\n<p>In <strong>Step 3<\/strong> the <code>main()<\/code> function will return an integer of zero to denote <strong>success<\/strong>, and any other value is an <strong>error status code<\/strong>.<\/p>\n\n\n\n<p>In <strong>step 4<\/strong> The <code>stdio.h<\/code> header function <code>int printf(const char *format, ...)<\/code>, has a signature that takes a C string type with variable arguments (0-to-many) values to perform a string interpolation. Similar to Java&rsquo;s <code>System.out.printf(&ldquo;Hello, %s\\n&rdquo;, &ldquo;Hello Panama!&rdquo;);<\/code>.<\/p>\n\n\n\n<p>There are two things to keep in mind when talking to C.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Be aware of C <code>#includes<\/code>. Header files on your system will allow <code>jextract<\/code> to generate code bindings (class files).<\/li>\n\n\n\n<li>Know that C&rsquo;s datatypes will need to be converted between Java and C as needed. Luckly, Panama will create convience methods that makes this easy!<\/li>\n<\/ul>\n\n\n\n<p>Now that we have a good understanding of a Hello World C program let&rsquo;s create an equivalent Panama Java Hello World example. In other words the Java program will natively call the <code>printf()<\/code> function.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h2-6--anama-ello-orld-xample\">Panama Hello World Example<\/h2>\n\n\n\n<p>As mentioned before, the C code of our Hello World program was using the <code>stdio.h<\/code> library. At this point, we will generate Java code to talk to the <code>stdio.h<\/code> library. Instead of hand coding this (which is out of the scope of this tutorial) we will be using the <code>jextract<\/code> tool. This magical tool will generate pure Java code that will bind to native libraries. These class files will contain meta data and much of the lower level Panama code that will make things convenient for the user of the API (you and me).<\/p>\n\n\n\n<p><strong>Note:<\/strong> When using jextract's switch <code>--output<\/code> it can emit or generate source code that can be used in projects. Here's where you can view Panama specific code.<\/p>\n\n\n\n<p>Because the C language specification is well defined <code>jextract<\/code> can generate Java code pretty easily. C++ on the other hand will be another effort and is not currently supported. If you have a native library written in C++ you&rsquo;d have to take some additional steps which I won&rsquo;t cover (See <a href=\"https:\/\/foojay.io\/today\/java-panama-polyglot-part1\/\">Java Panama Polyglot (C++) Part 1<\/a>).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h2-7--et-s-jextract-please-\">Let&rsquo;s jextract STDIO please!<\/h2>\n\n\n\n<p>The <code>jextract<\/code> tool has been updated to make it easier for standard C libraries by specifying header files in double quotes as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">jextract --output generatedsrc -t org.unix \"&lt;stdio.h&gt;\"<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>--output &lt;destination directory of generated java code&gt;<\/code><\/li>\n\n\n\n<li><code>-t<\/code> &lt;package namespace&gt;<\/li>\n\n\n\n<li><code>\"&lt;stdio.h&gt;\"<\/code> the standard header file to generate from surrounded by quotes.<\/li>\n<\/ul>\n\n\n\n<p>The generated Java (Panama) code will be placed in the directory <code>generatedsrc\/org\/unix<\/code><\/p>\n\n\n\n<p>It should look like the following:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bat\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$ ls -l generatedsrc\/org\/unix<\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>__darwin_pthread_rwlock_t.java\n__darwin_pthread_rwlockattr_t.java\n__mbstate_t.java\n__sbuf.java\n__sFILE.java\n_opaque_pthread_attr_t.java\n_opaque_pthread_cond_t.java\n_opaque_pthread_condattr_t.java\n_opaque_pthread_mutex_t.java\n... more<\/code><\/pre>\n\n\n\n<p>If you were successful in generating the code you can skip the next steps 1 &amp; 2 and go straight into step 3 where you begin to create the <code>HelloWorld.java<\/code> example using the generated Panama code.<\/p>\n\n\n\n<p>To use <code>jextract<\/code> let&rsquo;s locate where your <code>stdio.h<\/code> file is located on your local computer.<\/p>\n\n\n\n<p><strong>Step 1:<\/strong> (Optional Step) Find header file stdio.h<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$ gcc -H -fsyntax-only helloworld.c<\/pre>\n\n\n\n<p>On MacOS (Big Sur, Monterey) the output looks something to the following:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">. \/Applications\/Xcode.app\/Contents\/Developer\/Platforms\/MacOSX.platform\/Developer\/SDKs\/MacOSX.sdk\/usr\/include\/stdio.h\n.. \/Applications\/Xcode.app\/Contents\/Developer\/Platforms\/MacOSX.platform\/Developer\/SDKs\/MacOSX.sdk\/usr\/include\/_stdio.h\n...<\/pre>\n\n\n\n<p>Now that you know where the file is located, we can target the file when using the <code>jextract<\/code> tool.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$ jextract [options] &lt;path_to_file\/stdio.h&gt;<\/pre>\n\n\n\n<p><strong>Step 2:<\/strong> (<strong>Optional step<\/strong>) Use <code>jextract<\/code> to generate Java code from a specific <code>stdio.h<\/code> header file location using <code>-I<\/code> &lt;include files directory&gt;.<br><br>On MacOS do the following:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$ jextract --output generatedsrc -t org.unix -I \/Applications\/Xcode.app\/Contents\/Developer\/Platforms\/MacOSX.platform\/Developer\/SDKs\/MacOSX.sdk\/usr\/include \/Applications\/Xcode.app\/Contents\/Developer\/Platforms\/MacOSX.platform\/Developer\/SDKs\/MacOSX.sdk\/usr\/include\/stdio.h<\/pre>\n\n\n\n<p><strong>On Linux:<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$ jextract --output generatedsrc -t org.unix -I \/usr\/include \/usr\/include\/stdio.h<\/pre>\n\n\n\n<p>Now we can use the generated code to be used in our Panama Java Hello World program.<\/p>\n\n\n\n<p><strong>Step 3:<\/strong> Create a Java <code>HelloWorld.java<\/code> file<br><br>Copy and paste the following into a file <code>HelloWorld.java<\/code>.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import static org.unix.stdio_h.*;\n\nvoid main() {\n   \/\/ Use a confined arena for deterministic memory management\n   try (Arena arena = Arena.ofConfined()) {\n       \/\/ MemorySegment C's printf using a C string\n       MemorySegment cString = arena.allocateFrom(\"Hello World! Panama style\\n\");\n       int charCount = printf.makeInvoker().apply(cString);\n   }\n}<\/pre>\n\n\n\n<p><strong>Step 4:<\/strong> Compiling <strong>generated files<\/strong> along with <code>HelloWorld.java<\/code><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Compile Jextract generated Java code in generatedsrc\njavac generatedsrc\/org\/**\/*.java -d classes\n\n# Compile Example Java code in src\njavac -cp .:classes src\/*.java -d classes<\/pre>\n\n\n\n<p><strong>Step 5:<\/strong> Running the Panama Java <code>HelloWorld.java<\/code><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$ java -cp .:classes \\\n --enable-native-access=ALL-UNNAMED \\\n HelloWorld<\/pre>\n\n\n\n<p>The output is the following:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Hello World! Panama style<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h2-8--ow-does-it-work-\">How does it work?<\/h2>\n\n\n\n<p><strong>Step 1<\/strong>, the C compiler on MacOS\/Linux platforms allows you to find where headers are located on a system. Often MacOS developers will use Brew (package manager) to install 3rd party libraries such as OpenCL, Tensorflow, etc.<\/p>\n\n\n\n<p><strong>Step 2<\/strong> This is where the magic happens. The <code>jextract<\/code> tool will generate the source code using <code>--<\/code>output. The <code>-t<\/code> is the namespace on the class path. The older <code>jextract<\/code> tool used to compile the generated Java code, but now only outputs Java source code. <code>-I<\/code> (dash capitol &lsquo;i&rsquo;) specifies the directory of include files. If you want to target other directories just specify additional <code>-I &lt;dir_path_to_header_files&gt;<\/code> (Include switches).<\/p>\n\n\n\n<p>The targeting file path to the header file (<code>stdio.h<\/code>) is the last argument to <code>jextract<\/code>. Now for standard header files can be specified with double quotes similar to how they are imported in native C code.<\/p>\n\n\n\n<p><strong>Step 3<\/strong> HelloWorld.java file you'll notice the file doesn't contain the public HelloWorld class and the <code>main()<\/code> is more concise. That is because it is new in Java as of Java 25's <a target=\"_blank\" href=\"https:\/\/openjdk.org\/jeps\/512\">JEP 512<\/a> Compact classes - Concise Java code. Other conveniences such as <code>IO.println()<\/code> and many others.<\/p>\n\n\n\n<p>You may notice that calling C's&nbsp;<code>printf()<\/code>&nbsp;has changed significantly since the early FFI incubator stages. More on this later, but for now just know that jextract will generate two methods <code>makeInvoker()<\/code> and <code>apply()<\/code> to C functions having variable arguments (known as a <em>variadic function<\/em>).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int charCount = printf.makeInvoker().apply(cString);<\/code><\/pre>\n\n\n\n<p><code>.makeInvoker(MemoryLayout...)<\/code> - Returns an instance of a <code>printf<\/code> object.<\/p>\n\n\n\n<p><code>.apply(MemorySegment cCharArray, Object... values)<\/code> - Invokes <code>printf()<\/code> function with values and returns an <code>int<\/code> . <\/p>\n\n\n\n<p>Upon successful execution,&nbsp;<code>printf()<\/code>&nbsp;returns the total character count of the output. If the function encounters an issue, it returns a negative integer instead.<\/p>\n\n\n\n<p><strong>Step 4<\/strong> Compiling both generated source code and HelloWorld.java. <\/p>\n\n\n\n<p><strong>Step 5<\/strong> Running HelloWorld. <code>-cp<\/code> denotes the class path of the compiled classes, <code>--enable-native-access=ALL-UNNAMED<\/code> will enable access to native code and stop warnings from outputting.<\/p>\n\n\n\n<p>-cp .:classes \\<br>--enable-native-access=ALL-UNNAMED \\<br>HelloWorld<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h3-9--hat-about-3rd-party-libraries-\">What about 3rd party C libraries?<\/h3>\n\n\n\n<p>When 3rd party libraries are installed they typically are in your library path such as <code>\/usr\/lib<\/code> or <code>\/usr\/local\/lib<\/code>. To specify a library the <code>-l<\/code> (lowercase 'L') option is used. The value will be the name of the library or the absolute path to the library. For example, say you want to use Tensorflow (Google's Machine Learning library).<\/p>\n\n\n\n<p>On the Mac OS the file would be named <code>libtensorflow.dylib<\/code> and on Linux should be <code>tensorflow.so<\/code>. I believe on Windows OS it should be named <code>tensorflow.dll<\/code>.<\/p>\n\n\n\n<p>To specify <code>-l<\/code> (option L) you can specify the name of the library or the absolute path of the library file. For example, to jextract Tensorflow it will look like the following:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$ jextract \\\n  -I \/Applications\/Xcode.app\/Contents\/Developer\/Platforms\/MacOSX.platform\/Developer\/SDKs\/MacOSX.sdk\/usr\/include\/ \\\n  -t org.tensorflow \\\n  -I ${LIBTENSORFLOW_HOME}\/include \\\n  -l ${LIBTENSORFLOW_HOME}\/lib\/libtensorflow.dylib \\\n  ${LIBTENSORFLOW_HOME}\/include\/tensorflow\/c\/c_api.h<\/pre>\n\n\n\n<p>You will notice on MacOS I specified the fully qualified library file <code>${LIBTENSORFLOW_HOME}\/lib\/libtensorflow.dylib<\/code> instead of the name (tensorflow). Usually, if libraries are installed in \/usr\/lib or \/usr\/local\/lib you can just specify the name.<\/p>\n\n\n\n<p><strong>Step 3:<\/strong> Java code talks to C.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> void main() {\n    \/\/ Use a confined arena for deterministic memory management\n    try (Arena arena = Arena.ofConfined()) {                 \/\/ (A)\n        \/\/ MemorySegment C's printf using a C string\n        MemorySegment cString = arena.allocateFrom(\"Hello World! Panama style\\n\"); \/\/ (B)\n        int charCount = printf.makeInvoker().apply(cString); \/\/ (C)\n    }\n }<\/pre>\n\n\n\n<p>In line <strong>(A) <\/strong>the statement is where the code uses a try with resources to create an <code>Arena<\/code>. An Arena is type of scope <a target=\"_blank\" href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/25\/docs\/api\/java.base\/java\/lang\/foreign\/Arena.html#ofConfined()\">confined<\/a> will auto close when it's finished after the try-block. This will deallocate native memory safely. Please see the javadoc documentation for additional types of <a target=\"_blank\" href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/25\/docs\/api\/java.base\/java\/lang\/foreign\/Arena.html\">Arenas<\/a>.<\/p>\n\n\n\n<p>The statement in line <strong>(B)<\/strong> calls the <code>allocateFrom(String)<\/code> method to allocate and convert a Java String into a C string (<code>char <em><\/em><\/code><em> type). Any time you are mimicking C variables they will be of type <code>MemorySegment<\/code>. In <a href=\"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-2\/\" target=\"_blank\" rel=\"noreferrer noopener\">part 2<\/a> of this series we will look at C pointers (address), so if you find the asterisk beside the <code>char <\/code><\/em> type a little odd, don't be too concerned about it for now, and just know that it is the C language's way of storing a string value (or array of characters and null terminated).<\/p>\n\n\n\n<p>In statement <strong>(C)<\/strong> the makeInvoker() method  <\/p>\n\n\n\n<p>In statement <strong>(C)<\/strong> the call to the native function <code>printf()<\/code> with the object <code>cString<\/code> of type <code>MemorySegement<\/code> is passed in and invoked. Another important note to understand is <code>stdout<\/code> (Standard output) in C, when used in combination with Java's System.out.printlin() you may need to <strong>flush<\/strong> the native side first for instance:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var cString = arena.allocateFrom(\"Hello World (Native C Called)\\n\");\nprintf.makeInvoker().apply(cString);\nSystem.out.println(\"Java System.out\\n\");<\/pre>\n\n\n\n<p>On some systems, (on MacOS) the following output occurs because of the C's output hasn't been flushed:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Java System.out\nHello World (Native C Called)<\/pre>\n\n\n\n<p>So, what do you do? You need to call <code>fflush()<\/code>to flush C's buffer to <code>stdout<\/code>.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var cString = arena.allocateFrom(\"Hello World (Native C Called)\\n\");\nprintf.makeInvoker().apply(cString);\nfflush(NULL()); \/\/ jextract generated functions in org.unix.stdio_h.*\nSystem.out.println(\"Java System.out\\n\");<\/pre>\n\n\n\n<p>Now, the output will be in the correct order shown below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Hello World (Native C Called)\nJava System.out<\/pre>\n\n\n\n<p>So, now that you know how to output a newly created C string using the printf() function let's learn how to substitute values into a <strong>format string<\/strong> or string template. Java's <code>System.out.printf()<\/code> also has the same calling convention as C's <code>stdio.h<\/code> <code>printf()<\/code> function. Let's examine a format string passed into the printf() function.<\/p>\n\n\n\n<p>In the example below, the&nbsp;<code>%s<\/code>&nbsp;format specifier is substituted with the string \"Fred\":<\/p>\n\n\n\n<p><code>printf(\"Hello %s!\", \"Fred\"); \/\/ Output: Hello Fred!<\/code><\/p>\n\n\n\n<p>When using the Foreign Function &amp; Memory (FFM) API, you must define the function's data types using a&nbsp;<code>FunctionDescriptor<\/code>&nbsp;before it can be invoked. In this case, the&nbsp;<code>printf<\/code>&nbsp;function expects a&nbsp;<code>char*<\/code>&nbsp;(a C string), which is a pointer.<\/p>\n\n\n\n<p><strong>Manual Layout:<\/strong>&nbsp;If you are <strong>not <\/strong>using&nbsp;<strong>jextract<\/strong>, use&nbsp;<code>ValueLayout.ADDRESS<\/code>&nbsp;to represent a pointer to a memory segment. In this case we want to pass a <code>char*<\/code> so we use the ADDRESS layout. Because pointers in C are just an address.<\/p>\n\n\n\n<p><strong>Using jextract:<\/strong>&nbsp;If you generate bindings via&nbsp;<a href=\"https:\/\/github.com\/openjdk\/jextract\" target=\"_blank\" rel=\"noreferrer noopener\">jextract<\/a>, the tool will typically provide a platform-specific constant like&nbsp;<code>stdio_h.C_POINTER<\/code>&nbsp;to handle these address values for any C pointer type.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Memory Allocation:<\/strong>&nbsp;You cannot pass a Java&nbsp;<code>String<\/code>&nbsp;directly to C. You must first use an&nbsp;<code>Arena<\/code>&nbsp;to allocate a&nbsp;<code>MemorySegment<\/code>&nbsp;that holds the string's bytes in off-heap memory. To call C <code>printf()<\/code> we need to allocate <code>const char *<\/code> memory segment within a arena and pass the memory segment to the C <code>printf()<\/code> function.<\/li>\n\n\n\n<li><strong>Variadic Arguments:<\/strong>&nbsp;If you are manually calling printf (not using jextract) you would need to call the <code>downcallHandle()<\/code> method on the Linker object. Calling a function with variadic arguments is more of an advanced topic and we can stick to the functions (methods) generated by jextract. But for those that are curious you want to look at the Linker object's <code>downcallHandle()<\/code> method. <\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>MethodHandle downcallHandle(MemorySegment address,\n                                FunctionDescriptor function,\n                                Option... options);<\/code><\/pre>\n\n\n\n<p>Let's get back to where we left off regarding MemoryLayouts specified prior to invoking (apply() method) printf.<\/p>\n\n\n\n<p>Below shows the static method on the printf class called <code>makeInvoker(ValueLayout... (variable arguments))<\/code>. We specify the first variadic argument to be of type C_POINTER.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">MemorySegment formatCStr = arena.allocateFrom(\"Hello %s!\\n\");\nprintf printfAlpha = printf.makeInvoker(stdio_h.C_POINTER);\n\nMemorySegment nameStr = arena.allocateFrom(\"Fred\");\n\nprintfAlpha.apply(formatCStr, nameStr); \/\/ Hello Fred!<\/pre>\n\n\n\n<p>The following shows commonly used format specifiers (not an exhaustive list).<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-regular\"><table class=\"has-fixed-layout\"><thead><tr><th><strong>Format Specifier&nbsp;<\/strong><\/th><th><strong>Data Type<\/strong><\/th><th><strong>Description<\/strong><\/th><\/tr><\/thead><tbody><tr><td><code>%d<\/code>&nbsp;or&nbsp;<code>%i<\/code><\/td><td><code>int<\/code>&nbsp;(signed)<\/td><td>Prints a signed decimal integer.<\/td><\/tr><tr><td><code>%f<\/code>&nbsp;or&nbsp;<code>%F<\/code><\/td><td><code>float<\/code>,&nbsp;<code>double<\/code><\/td><td>Prints a floating-point number in scientific (exponential) notation.<\/td><\/tr><tr><td><code>%s<\/code><\/td><td><code>char*<\/code>(string)<\/td><td>Prints a sequence of characters until a null terminator (<code>\\0<\/code>) is found.<\/td><\/tr><tr><td><code>%p<\/code><\/td><td>Pointer (<code>void*<\/code>)<\/td><td>Prints a memory address, typically in hexadecimal format.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Let's look at a more advanced format string using different format specifiers. To begin we will examine the following C code to be translated to Panama (FFI &amp; FFM) code.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int charCount = printf(\"%s is %d years old and is %.1f feet tall.\\n\", \"Fred\", 60, 5.9d);<\/pre>\n\n\n\n<p>Above you'll notice <code>%s<\/code>, <code>%d<\/code> and <code>%.1f<\/code> which tells you there are <strong>three<\/strong> format specifiers: C string, int, and double(floating point number). Now we can call the <code>makeInvoker()<\/code> method with the appropriate data types generated from jextract. The types would be the following: <code>C_POINTER<\/code>, <code>C_INT<\/code>, and <code>C_DOUBLE<\/code>.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">    void main() {\n       try (Arena arena = Arena.ofConfined()) { \n         \/\/ *******************************************************************************\n         \/\/ * How to call printf() with format string such as\n         \/\/ * printf(\"%s is %d years old and is %.1f feet tall.\\\", \"Fred\", 60, 5.9f);\n         \/\/ *******************************************************************************\n         MemorySegment formatCStr = arena.allocateFrom(\"%s is %d years old and is %.1f feet tall.\\n\");\n         MemorySegment nameCStr = arena.allocateFrom(\"Fred\");\n\n         \/\/ Create an instance of a generated org.unix.printf class from jextract. (FYI, class is named all lowercase)\n         printf printfAlpha = printf.makeInvoker(\n                stdio_h.C_POINTER,  \/* 2nd param - C string %s. A pointer to character array address *\/\n                stdio_h.C_INT,      \/* 3rd param - C int %d. Integer value (32bit whole number) *\/\n                stdio_h.C_DOUBLE);  \/* 4th param - C double %f. Floating point decimal. floats promote to a double*\/\n\n         int charCount = printfAlpha.apply(\n                                        formatCStr,\n                                        nameCStr,\n                                        60,\n                                        5.9f);\n       }\n    }<\/pre>\n\n\n\n<p>This time I separated the calls <code>makeInvoker()<\/code> and <code>apply()<\/code> instead of the earlier example of method chaining. By separating the calls you can see <code>makeInvoker()<\/code> returns an instance of a <code>printf<\/code> object capable of receiving 3 variadic arguments (<code>\"Fred\", 60, 5.9d<\/code>). The first parameter will be the <strong>format string<\/strong> <code>\"%s is %d years old and is %.1f feet tall.\\n\"<\/code>.<\/p>\n\n\n\n<p>The output is:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Fred is 60 years old and is 5.9 feet tall.<\/pre>\n\n\n\n<p>Congratulations for getting this far! While it's nice to create and output C strings. Let's look at how to create primitive data types off of the Java's memory heap. <\/p>\n\n\n\n<p>Let's look at how to create C primitive data types and later how to create arrays of primitives.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h3-10--reating-etting-etting-primitive-data-types-from-ava\">Creating\/Getting\/Setting C primitive data types from Java<\/h3>\n\n\n\n<p>To make this easy to remember think of <code>AllocatorFrom -&gt; MemorySegment -&gt; get\/set<\/code> (<code>aka MemSeg<\/code> pattern). When creating C primitive data (variables) remember that they are like objects where space is allocated and has a memory addresses to change or access the value (dereferenced).<\/p>\n\n\n\n<p><strong>Creating a C String or C primitive call an Arena instance's <code>allocateFrom()<\/code> method.<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>String<\/code> - <code>allocateFrom(String str)<\/code>, <code>allocateFrom(String str, CharSet cs)<\/code> <br><strong>e.g.<\/strong> <code>arena.allocateFrom(\"hello\", UTF_8)<\/code><\/li>\n\n\n\n<li><code>byte<\/code> - <code>allocateFrom(ValueLayout.OfByte layout, byte value)<\/code><\/li>\n\n\n\n<li><code><code>boolean<\/code><\/code> - <code>allocateFrom(ValueLayout.OfBoolean layout, <code>boolean<\/code> value)<\/code><\/li>\n\n\n\n<li><code>char<\/code> - <code>allocateFrom(ValueLayout.OfChar layout, char value)<\/code><\/li>\n\n\n\n<li><code><code>double<\/code><\/code> - <code>allocateFrom(ValueLayout.Of<code>Double<\/code> layout, <code>double<\/code> value)<\/code><\/li>\n\n\n\n<li><code><code>float<\/code><\/code> - <code>allocateFrom(ValueLayout.OfFloat layout, <code>float<\/code> value)<\/code><\/li>\n\n\n\n<li><code><code>int<\/code><\/code> - <code>allocateFrom(ValueLayout.OfInt layout, <code>int<\/code> value)<\/code><\/li>\n\n\n\n<li><code><code>long<\/code><\/code> - <code>allocateFrom(ValueLayout.OfLong layout, <code>long<\/code> value)<\/code><\/li>\n\n\n\n<li><code><code>short<\/code><\/code> - <code>allocateFrom(ValueLayout.OfShort layout, <code>short<\/code> value)<\/code><\/li>\n<\/ul>\n\n\n\n<p><strong>Note:<\/strong> I've only listed out the common methods used. There are many other overloaded methods to choose from that will allow you to create arrays, structs and custom memory layouts.<\/p>\n\n\n\n<p><strong>Getting primitive data from a <code>MemorySegment<\/code> object the following are special get() methods:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>byte - get(ValueLayout.OfByte, long offset)<\/code><\/li>\n\n\n\n<li><code>boolean - get(ValueLayout.OfBoolean, long offset)<\/code><\/li>\n\n\n\n<li>char<code> - get(ValueLayout.OfChar, long offset)<\/code><\/li>\n\n\n\n<li><code>double - get(ValueLayout.OfDouble, long offset)<\/code><\/li>\n\n\n\n<li><code>float - get(ValueLayout.OfFloat, long offset)<\/code><\/li>\n\n\n\n<li><code>int - get(ValueLayout.OfInt, long offset)<\/code><\/li>\n\n\n\n<li><code>long - get(ValueLayout.OfLong, long offset)<\/code><\/li>\n\n\n\n<li><code>short - get(ValueLayout.OfShort, long offset)<\/code><\/li>\n<\/ul>\n\n\n\n<p>Note: there are other overloaded methods to create custom memory layouts<\/p>\n\n\n\n<p><strong>Setting primitive data to a <code>MemorySegment<\/code> object:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>byte - set(ValueLayout.OfByte, long offset, byte value)<\/code><\/li>\n\n\n\n<li><code>boolean - set(ValueLayout.OfBoolean, long offset<code>, <code>boolean<\/code> value<\/code>)<\/code><\/li>\n\n\n\n<li>char<code> - set(ValueLayout.OfChar, long offset<code>, char value<\/code>)<\/code><\/li>\n\n\n\n<li><code>double - set(ValueLayout.OfDouble, long offset<code>, double value<\/code>)<\/code><\/li>\n\n\n\n<li><code>float - set(ValueLayout.OfFloat, long offset<code>, float value<\/code>)<\/code><\/li>\n\n\n\n<li><code>int - set(ValueLayout.OfInt, long offset<code>, int value<\/code>)<\/code><\/li>\n\n\n\n<li><code>long - set(ValueLayout.OfLong, long offset<code>, long value<\/code>)<\/code><\/li>\n\n\n\n<li><code>short - set(ValueLayout.OfShort, long offset<code>, short value<\/code>)<\/code><\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">MemorySegment formatCStr = arena.allocateFrom(\"A slice of %f \\n\");\n\n\/\/ Create an off heap double containing the value of Pi.\nMemorySegment cDouble = arena.allocateFrom(C_DOUBLE, Math.PI);\n\n\/\/ Create an instance of a printf object via makeInvoker() that accepts a double (%f floating point number)\nprintf printfFun = printf.makeInvoker(C_DOUBLE); \n\n\/\/ Invoke printf function such as printf(\"A slice of %f \\n\", 3.141593d); \nprintfFun.apply(formatCStr, cDouble.get(C_DOUBLE, 0)); \/\/ A slice of 3.141593<\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Output:\nA slice of 3.141593<\/code><\/pre>\n\n\n\n<p>Of course you can also call by passing in Java's <code>Math.PI<\/code> (primitive double) into the function.<\/p>\n\n\n\n<p><code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">printfFun.apply(cFormatStr, Math.PI); \/\/ A slice of 3.141593<\/code><\/p>\n\n\n\n<p><strong>Note:<\/strong> It's better to use the <code>jextract<\/code> generated <code>stdio_h.C_DOUBLE<\/code> (as opposed to <code>ValueLayout.JAVA_DOUBLE<\/code>) because it takes on the underlying OS' bit width. It might not occupy the same number of bits if you are assuming it's 64 bits (8 bytes). The following is the <code>C_DOUBLE<\/code> variable of type <code>OfDouble<\/code> that gets generated by <code>jextract<\/code> as follows.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ jextract generated C_DOUBLE\npublic static final ValueLayout.OfDouble C_DOUBLE = (ValueLayout.OfDouble) Linker.nativeLinker().canonicalLayouts().get(\"double\");<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h3-11--reating-primitive-arrays\">Creating C primitive arrays<\/h3>\n\n\n\n<p>Now that you know how to create primitive data types let's create C primitive arrays. Shown below is allocating space to hold a single dimensional array off of the Java heap. Then we just re-access the C array using <code>getAtIndex(ValueLayout, index)<\/code> and then displaying the contents.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">out.println(\"An array of data\");\nMemorySegment cDoubleArray = arena.allocateFrom(C_DOUBLE, \n       1.0, 2.0, 3.0, 4.0,\n       1.0, 1.0, 1.0, 1.0,\n       3.0, 4.0, 5.0, 6.0,\n       5.0, 6.0, 7.0, 8.0\n);\n\nfor (long i = 0; i &lt; (4*4); i++) {\n   if (i&gt;0 &amp;&amp; i % 4 == 0) {\n       System.out.println();\n   }\n   out.printf(\" %f \", cDoubleArray.getAtIndex(C_DOUBLE, i));\n}<\/pre>\n\n\n\n<p>The output:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">An array of data\n 1.000000  2.000000  3.000000  4.000000 \n 1.000000  1.000000  1.000000  1.000000 \n 3.000000  4.000000  5.000000  6.000000 \n 5.000000  6.000000  7.000000  8.000000 <\/pre>\n\n\n\n<p>As demonstrated above, you can use the&nbsp;<code>MemorySegment.getAtIndex(ValueLayout, index)<\/code>&nbsp;method to extract and display a specific value from the array. <\/p>\n\n\n\n<p>To change the array's values, you'll need to call the&nbsp;<code>MemorySegment.setAtIndex()<\/code>&nbsp;method. The provided example below shows how to fetch each value and multiply it by 3.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">for (long i = 0; i &lt; 16; i++) {\n   double newVal = cDoubleArray.getAtIndex(C_DOUBLE, i) * 3;\n   cDoubleArray.setAtIndex(C_DOUBLE, i, newVal);\n}<\/pre>\n\n\n\n<p class=\"has-text-align-left\">Output is shown below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> 3.000000  6.000000  9.000000  12.000000 \n 3.000000  3.000000  3.000000  3.000000 \n 9.000000  12.000000  15.000000  18.000000 \n 15.000000  18.000000  21.000000  24.000000 <\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Conclusion<\/h1>\n\n\n\n<p>In Part 1, we learned about the what, where, and whys regarding project Panama. Next, we examined the anotomy of a typical Hello World C program. After learning how to use <code>jextract<\/code> to generate Java code from <code>stdio.h<\/code>, we were able to create a Java Hello World to access the C function <code>printf()<\/code>. Lastly, we learned how to create C primitive data types including arrays.<\/p>\n\n\n\n<p>If you're still interested,<a href=\"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-2\/\"> in Part 2 we will continue our journey into Project Panama<\/a>, by looking at C's concept of <strong>structs<\/strong> and <strong>pointers<\/strong>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Resources<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Panama4Newbies: <a target=\"_blank\" href=\"https:\/\/github.com\/carldea\/panama4newbies\">https:\/\/github.com\/carldea\/panama4newbies<\/a><\/li>\n\n\n\n<li>Panama4Newbies part 1 source: <a target=\"_blank\" href=\"https:\/\/github.com\/carldea\/panama4newbies\/tree\/main\/part01\">https:\/\/github.com\/carldea\/panama4newbies\/tree\/main\/part01<\/a><\/li>\n\n\n\n<li>Interconnecting Java and Native Code with the FFM API - JavaOne 2025 : <a target=\"_blank\" href=\"https:\/\/www.youtube.com\/watch?v=Bhh07Rz5enw\">https:\/\/www.youtube.com\/watch?v=Bhh07Rz5enw<\/a><\/li>\n\n\n\n<li>OpenJDK's Project Panama - <a target=\"_blank\" href=\"https:\/\/openjdk.java.net\/projects\/panama\/\">https:\/\/openjdk.java.net\/projects\/panama\/<\/a><\/li>\n\n\n\n<li>jextract releases - <a target=\"_blank\" href=\"https:\/\/jdk.java.net\/jextract\/\">http:\/\/jdk.java.net\/panama\/<\/a><\/li>\n\n\n\n<li>Mailing list: - <a target=\"_blank\" href=\"https:\/\/mail.openjdk.java.net\/mailman\/listinfo\/panama-dev\">https:\/\/mail.openjdk.java.net\/mailman\/listinfo\/panama-dev<\/a><\/li>\n\n\n\n<li>Fosdem 2022 Project Panama talk <br>Native Language Access: Project Panama for Newbies (Carl Dea): <a target=\"_blank\" href=\"https:\/\/youtu.be\/REyl4cOsItE\">https:\/\/youtu.be\/REyl4cOsItE<\/a><\/li>\n\n\n\n<li>Panama Examples: <a target=\"_blank\" href=\"https:\/\/hg.openjdk.java.net\/panama\/dev\/raw-file\/4810a7de75cb\/doc\/panama_foreign.html#using-panama-foreign-jdk\">https:\/\/hg.openjdk.java.net\/panama\/dev\/raw-file\/4810a7de75cb\/doc\/panama_foreign.html#using-panama-foreign-jdk<\/a><\/li>\n\n\n\n<li>Minecraft - <a target=\"_blank\" href=\"https:\/\/www.minecraft.net\/en-us\">https:\/\/www.minecraft.net\/en-us<\/a><\/li>\n\n\n\n<li>LWJGL and JNI - <a target=\"_blank\" href=\"https:\/\/github.com\/LWJGL\/lwjgl3\/blob\/master\/config\/macos\/build.xml\">https:\/\/github.com\/LWJGL\/lwjgl3\/blob\/master\/config\/macos\/build.xml<\/a><\/li>\n\n\n\n<li>JNI: <a target=\"_blank\" href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/technotes\/guides\/jni\/\">https:\/\/docs.oracle.com\/javase\/8\/docs\/technotes\/guides\/jni\/<\/a><\/li>\n<\/ul>\n<\/body><\/html>\n","protected":false},"excerpt":{"rendered":"<p>In this series of articles, we will explore the APIs from OpenJDK\u2019s Project Panama. <\/p>\n<p>My intent is to show you how to be proficient in using the Foreign Linker APIs (module \u2018jdk.incubator.foreign\u2019) as it relates to Java interoperability with native code.<\/p>\n<p>While this article is for newbies, I assume you know the basics of the Java language, a little bash scripting, and a familiarity with C programming concepts. If you are new to C language don\u2019t worry I will go over the concepts later.<\/p>\n","protected":false},"author":32,"featured_media":46303,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[398,537],"tags":[542,548,549,33,545,546,508,539,541,547,543,35,540,544],"class_list":["post-46300","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-jeps","category-project-panama","tag-c-c","tag-coding","tag-hacking","tag-java","tag-java-17","tag-jep389","tag-jni","tag-minecraft","tag-native","tag-newbies","tag-opengl","tag-openjdk","tag-panama","tag-tensorflow"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Project Panama for Newbies (Part 1) | Foojay Today<\/title>\n<meta name=\"description\" content=\"Learn how the Java programming language has new ways to access native libraries that are written in native languages like C, C++, and Fortran.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Project Panama for Newbies (Part 1) | Foojay Today\" \/>\n<meta property=\"og:description\" content=\"Learn how the Java programming language has new ways to access native libraries that are written in native languages like C, C++, and Fortran.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/\" \/>\n<meta property=\"og:site_name\" content=\"foojay\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-01T09:11:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-01-22T00:11:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/foojay.io\/wp-content\/uploads\/2021\/08\/duke_and_panama.png\" \/>\n\t<meta property=\"og:image:width\" content=\"226\" \/>\n\t<meta property=\"og:image:height\" content=\"407\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Carl Dea\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Carl Dea\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/\"},\"author\":{\"name\":\"Carl Dea\",\"@id\":\"https:\\\/\\\/foojay.io\\\/#\\\/schema\\\/person\\\/774bdbf9584c717608454ad20475bb87\"},\"headline\":\"Project Panama for Newbies (Part 1)\",\"datePublished\":\"2026-01-01T09:11:00+00:00\",\"dateModified\":\"2026-01-22T00:11:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/\"},\"wordCount\":3911,\"commentCount\":20,\"publisher\":{\"@id\":\"https:\\\/\\\/foojay.io\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/foojay.io\\\/wp-content\\\/uploads\\\/2021\\\/08\\\/duke_and_panama.png\",\"keywords\":[\"C\\\/C++\",\"coding\",\"hacking\",\"Java\",\"Java 17\",\"jep389\",\"JNI\",\"Minecraft\",\"native\",\"newbies\",\"OpenGL\",\"OpenJDK\",\"Panama\",\"Tensorflow\"],\"articleSection\":[\"JEPs\",\"Project Panama\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/\",\"url\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/\",\"name\":\"Project Panama for Newbies (Part 1) | Foojay Today\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/foojay.io\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/foojay.io\\\/wp-content\\\/uploads\\\/2021\\\/08\\\/duke_and_panama.png\",\"datePublished\":\"2026-01-01T09:11:00+00:00\",\"dateModified\":\"2026-01-22T00:11:06+00:00\",\"description\":\"Learn how the Java programming language has new ways to access native libraries that are written in native languages like C, C++, and Fortran.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/#primaryimage\",\"url\":\"https:\\\/\\\/foojay.io\\\/wp-content\\\/uploads\\\/2021\\\/08\\\/duke_and_panama.png\",\"contentUrl\":\"https:\\\/\\\/foojay.io\\\/wp-content\\\/uploads\\\/2021\\\/08\\\/duke_and_panama.png\",\"width\":226,\"height\":407,\"caption\":\"Java's Project Panama\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/foojay.io\\\/today\\\/project-panama-for-newbies-part-1\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/foojay.io\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Project Panama for Newbies (Part 1)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/foojay.io\\\/#website\",\"url\":\"https:\\\/\\\/foojay.io\\\/\",\"name\":\"foojay\",\"description\":\"a place for friends of OpenJDK\",\"publisher\":{\"@id\":\"https:\\\/\\\/foojay.io\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/foojay.io\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/foojay.io\\\/#organization\",\"name\":\"foojay\",\"url\":\"https:\\\/\\\/foojay.io\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/foojay.io\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/foojay.io\\\/wp-content\\\/uploads\\\/2020\\\/04\\\/cropped-Favicon.png\",\"contentUrl\":\"https:\\\/\\\/foojay.io\\\/wp-content\\\/uploads\\\/2020\\\/04\\\/cropped-Favicon.png\",\"width\":512,\"height\":512,\"caption\":\"foojay\"},\"image\":{\"@id\":\"https:\\\/\\\/foojay.io\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/foojay2020\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/foojay.io\\\/#\\\/schema\\\/person\\\/774bdbf9584c717608454ad20475bb87\",\"name\":\"Carl Dea\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6ed5212dd2bf34bf1e83c4114019f1d3ee2b2c61419f98d03a4be72c50b939c4?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6ed5212dd2bf34bf1e83c4114019f1d3ee2b2c61419f98d03a4be72c50b939c4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6ed5212dd2bf34bf1e83c4114019f1d3ee2b2c61419f98d03a4be72c50b939c4?s=96&d=mm&r=g\",\"caption\":\"Carl Dea\"},\"description\":\"Carl Dea is a Lead Developer and Software Engineer at Deloitte. He has authored Java books and has been developing software for 20+ years with many clients, from Fortune 500 companies to nonprofit organizations. He has written software ranging from mission-critical applications to e-commerce applications. Carl has been using Java since the very beginning (when Applets were cool) and is a JavaFX enthusiast (fanboy) dating back to when it used to be called F3\\\/JavaFX script. He greatly loves sharing and advocating Java based technologies.\",\"sameAs\":[\"http:\\\/\\\/carlfx.wordpress.com\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/carldea\\\/\",\"https:\\\/\\\/x.com\\\/carldea\",\"https:\\\/\\\/www.youtube.com\\\/user\\\/carldea\"],\"url\":\"https:\\\/\\\/foojay.io\\\/today\\\/author\\\/carldea\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Project Panama for Newbies (Part 1) | Foojay Today","description":"Learn how the Java programming language has new ways to access native libraries that are written in native languages like C, C++, and Fortran.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/","og_locale":"en_US","og_type":"article","og_title":"Project Panama for Newbies (Part 1) | Foojay Today","og_description":"Learn how the Java programming language has new ways to access native libraries that are written in native languages like C, C++, and Fortran.","og_url":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/","og_site_name":"foojay","article_published_time":"2026-01-01T09:11:00+00:00","article_modified_time":"2026-01-22T00:11:06+00:00","og_image":[{"width":226,"height":407,"url":"https:\/\/foojay.io\/wp-content\/uploads\/2021\/08\/duke_and_panama.png","type":"image\/png"}],"author":"Carl Dea","twitter_misc":{"Written by":"Carl Dea","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/#article","isPartOf":{"@id":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/"},"author":{"name":"Carl Dea","@id":"https:\/\/foojay.io\/#\/schema\/person\/774bdbf9584c717608454ad20475bb87"},"headline":"Project Panama for Newbies (Part 1)","datePublished":"2026-01-01T09:11:00+00:00","dateModified":"2026-01-22T00:11:06+00:00","mainEntityOfPage":{"@id":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/"},"wordCount":3911,"commentCount":20,"publisher":{"@id":"https:\/\/foojay.io\/#organization"},"image":{"@id":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/foojay.io\/wp-content\/uploads\/2021\/08\/duke_and_panama.png","keywords":["C\/C++","coding","hacking","Java","Java 17","jep389","JNI","Minecraft","native","newbies","OpenGL","OpenJDK","Panama","Tensorflow"],"articleSection":["JEPs","Project Panama"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/","url":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/","name":"Project Panama for Newbies (Part 1) | Foojay Today","isPartOf":{"@id":"https:\/\/foojay.io\/#website"},"primaryImageOfPage":{"@id":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/#primaryimage"},"image":{"@id":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/foojay.io\/wp-content\/uploads\/2021\/08\/duke_and_panama.png","datePublished":"2026-01-01T09:11:00+00:00","dateModified":"2026-01-22T00:11:06+00:00","description":"Learn how the Java programming language has new ways to access native libraries that are written in native languages like C, C++, and Fortran.","breadcrumb":{"@id":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/#primaryimage","url":"https:\/\/foojay.io\/wp-content\/uploads\/2021\/08\/duke_and_panama.png","contentUrl":"https:\/\/foojay.io\/wp-content\/uploads\/2021\/08\/duke_and_panama.png","width":226,"height":407,"caption":"Java's Project Panama"},{"@type":"BreadcrumbList","@id":"https:\/\/foojay.io\/today\/project-panama-for-newbies-part-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/foojay.io\/"},{"@type":"ListItem","position":2,"name":"Project Panama for Newbies (Part 1)"}]},{"@type":"WebSite","@id":"https:\/\/foojay.io\/#website","url":"https:\/\/foojay.io\/","name":"foojay","description":"a place for friends of OpenJDK","publisher":{"@id":"https:\/\/foojay.io\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/foojay.io\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/foojay.io\/#organization","name":"foojay","url":"https:\/\/foojay.io\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/foojay.io\/#\/schema\/logo\/image\/","url":"https:\/\/foojay.io\/wp-content\/uploads\/2020\/04\/cropped-Favicon.png","contentUrl":"https:\/\/foojay.io\/wp-content\/uploads\/2020\/04\/cropped-Favicon.png","width":512,"height":512,"caption":"foojay"},"image":{"@id":"https:\/\/foojay.io\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/foojay2020"]},{"@type":"Person","@id":"https:\/\/foojay.io\/#\/schema\/person\/774bdbf9584c717608454ad20475bb87","name":"Carl Dea","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/6ed5212dd2bf34bf1e83c4114019f1d3ee2b2c61419f98d03a4be72c50b939c4?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/6ed5212dd2bf34bf1e83c4114019f1d3ee2b2c61419f98d03a4be72c50b939c4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6ed5212dd2bf34bf1e83c4114019f1d3ee2b2c61419f98d03a4be72c50b939c4?s=96&d=mm&r=g","caption":"Carl Dea"},"description":"Carl Dea is a Lead Developer and Software Engineer at Deloitte. He has authored Java books and has been developing software for 20+ years with many clients, from Fortune 500 companies to nonprofit organizations. He has written software ranging from mission-critical applications to e-commerce applications. Carl has been using Java since the very beginning (when Applets were cool) and is a JavaFX enthusiast (fanboy) dating back to when it used to be called F3\/JavaFX script. He greatly loves sharing and advocating Java based technologies.","sameAs":["http:\/\/carlfx.wordpress.com","https:\/\/www.linkedin.com\/in\/carldea\/","https:\/\/x.com\/carldea","https:\/\/www.youtube.com\/user\/carldea"],"url":"https:\/\/foojay.io\/today\/author\/carldea\/"}]}},"_links":{"self":[{"href":"https:\/\/foojay.io\/wp-json\/wp\/v2\/posts\/46300","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/foojay.io\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/foojay.io\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/foojay.io\/wp-json\/wp\/v2\/users\/32"}],"replies":[{"embeddable":true,"href":"https:\/\/foojay.io\/wp-json\/wp\/v2\/comments?post=46300"}],"version-history":[{"count":0,"href":"https:\/\/foojay.io\/wp-json\/wp\/v2\/posts\/46300\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/foojay.io\/wp-json\/wp\/v2\/media\/46303"}],"wp:attachment":[{"href":"https:\/\/foojay.io\/wp-json\/wp\/v2\/media?parent=46300"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/foojay.io\/wp-json\/wp\/v2\/categories?post=46300"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/foojay.io\/wp-json\/wp\/v2\/tags?post=46300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}