koffi 1.3.9 → 1.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/ChangeLog.md +12 -0
  2. package/build/qemu/1.3.10/koffi_darwin_arm64.tar.gz +0 -0
  3. package/build/qemu/1.3.10/koffi_darwin_x64.tar.gz +0 -0
  4. package/build/qemu/1.3.10/koffi_freebsd_arm64.tar.gz +0 -0
  5. package/build/qemu/1.3.10/koffi_freebsd_ia32.tar.gz +0 -0
  6. package/build/qemu/1.3.10/koffi_freebsd_x64.tar.gz +0 -0
  7. package/build/qemu/1.3.10/koffi_linux_arm32hf.tar.gz +0 -0
  8. package/build/qemu/1.3.10/koffi_linux_arm64.tar.gz +0 -0
  9. package/build/qemu/1.3.10/koffi_linux_ia32.tar.gz +0 -0
  10. package/build/qemu/1.3.10/koffi_linux_riscv64hf64.tar.gz +0 -0
  11. package/build/qemu/1.3.10/koffi_linux_x64.tar.gz +0 -0
  12. package/build/qemu/1.3.10/koffi_openbsd_ia32.tar.gz +0 -0
  13. package/build/qemu/1.3.10/koffi_openbsd_x64.tar.gz +0 -0
  14. package/build/qemu/1.3.10/koffi_win32_arm64.tar.gz +0 -0
  15. package/build/qemu/1.3.10/koffi_win32_ia32.tar.gz +0 -0
  16. package/build/qemu/1.3.10/koffi_win32_x64.tar.gz +0 -0
  17. package/doc/benchmarks.md +2 -2
  18. package/doc/conf.py +1 -1
  19. package/doc/contribute.md +1 -1
  20. package/doc/dist/doctrees/benchmarks.doctree +0 -0
  21. package/doc/dist/doctrees/changes.doctree +0 -0
  22. package/doc/dist/doctrees/contribute.doctree +0 -0
  23. package/doc/dist/doctrees/environment.pickle +0 -0
  24. package/doc/dist/doctrees/functions.doctree +0 -0
  25. package/doc/dist/doctrees/index.doctree +0 -0
  26. package/doc/dist/doctrees/memory.doctree +0 -0
  27. package/doc/dist/doctrees/types.doctree +0 -0
  28. package/doc/dist/html/.buildinfo +1 -1
  29. package/doc/dist/html/_sources/benchmarks.md.txt +2 -2
  30. package/doc/dist/html/_sources/contribute.md.txt +1 -2
  31. package/doc/dist/html/_sources/functions.md.txt +137 -15
  32. package/doc/dist/html/_sources/index.rst.txt +2 -0
  33. package/doc/dist/html/_sources/memory.md.txt +1 -1
  34. package/doc/dist/html/_sources/types.md.txt +27 -11
  35. package/doc/dist/html/_static/basic.css +14 -12
  36. package/doc/dist/html/_static/pygments.css +54 -54
  37. package/doc/dist/html/benchmarks.html +3 -3
  38. package/doc/dist/html/changes.html +1 -1
  39. package/doc/dist/html/contribute.html +2 -3
  40. package/doc/dist/html/functions.html +206 -86
  41. package/doc/dist/html/genindex.html +1 -1
  42. package/doc/dist/html/index.html +6 -7
  43. package/doc/dist/html/memory.html +4 -4
  44. package/doc/dist/html/objects.inv +0 -0
  45. package/doc/dist/html/platforms.html +2 -2
  46. package/doc/dist/html/search.html +1 -1
  47. package/doc/dist/html/searchindex.js +1 -1
  48. package/doc/dist/html/start.html +55 -55
  49. package/doc/dist/html/types.html +172 -159
  50. package/doc/functions.md +9 -7
  51. package/doc/index.rst +2 -0
  52. package/doc/memory.md +1 -1
  53. package/doc/poetry.lock +692 -0
  54. package/doc/pyproject.toml +18 -0
  55. package/doc/{_static → static}/bench_linux.png +0 -0
  56. package/doc/{_static → static}/bench_windows.png +0 -0
  57. package/doc/{_static → static}/custom.css +0 -0
  58. package/doc/{_static → static}/perf_linux_20220623.png +0 -0
  59. package/doc/{_static → static}/perf_linux_20220623_2.png +0 -0
  60. package/doc/{_static → static}/perf_linux_20220627.png +0 -0
  61. package/doc/{_static → static}/perf_linux_20220628.png +0 -0
  62. package/doc/{_static → static}/perf_windows_20220623.png +0 -0
  63. package/doc/{_static → static}/perf_windows_20220623_2.png +0 -0
  64. package/doc/{_static → static}/perf_windows_20220627.png +0 -0
  65. package/doc/{_static → static}/perf_windows_20220628.png +0 -0
  66. package/doc/types.md +1 -1
  67. package/package.json +1 -1
  68. package/qemu/qemu.js +3 -3
  69. package/src/abi_arm32.cc +3 -3
  70. package/src/abi_riscv64.cc +1 -1
  71. package/src/abi_x64_sysv.cc +1 -1
  72. package/src/abi_x64_win.cc +1 -1
  73. package/src/abi_x64_win_fwd.asm +2 -2
  74. package/src/abi_x86.cc +5 -5
  75. package/build/qemu/1.3.9/koffi_darwin_arm64.tar.gz +0 -0
  76. package/build/qemu/1.3.9/koffi_darwin_x64.tar.gz +0 -0
  77. package/build/qemu/1.3.9/koffi_freebsd_arm64.tar.gz +0 -0
  78. package/build/qemu/1.3.9/koffi_freebsd_ia32.tar.gz +0 -0
  79. package/build/qemu/1.3.9/koffi_freebsd_x64.tar.gz +0 -0
  80. package/build/qemu/1.3.9/koffi_linux_arm32hf.tar.gz +0 -0
  81. package/build/qemu/1.3.9/koffi_linux_arm64.tar.gz +0 -0
  82. package/build/qemu/1.3.9/koffi_linux_ia32.tar.gz +0 -0
  83. package/build/qemu/1.3.9/koffi_linux_riscv64hf64.tar.gz +0 -0
  84. package/build/qemu/1.3.9/koffi_linux_x64.tar.gz +0 -0
  85. package/build/qemu/1.3.9/koffi_openbsd_ia32.tar.gz +0 -0
  86. package/build/qemu/1.3.9/koffi_openbsd_x64.tar.gz +0 -0
  87. package/build/qemu/1.3.9/koffi_win32_arm64.tar.gz +0 -0
  88. package/build/qemu/1.3.9/koffi_win32_ia32.tar.gz +0 -0
  89. package/build/qemu/1.3.9/koffi_win32_x64.tar.gz +0 -0
@@ -5,7 +5,7 @@
5
5
  <meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
6
6
  <link rel="index" title="Index" href="genindex" /><link rel="search" title="Search" href="search" /><link rel="next" title="Function calls" href="functions" /><link rel="prev" title="Quick start" href="start" />
7
7
 
8
- <meta name="generator" content="sphinx-5.0.2, furo 2022.06.21"/>
8
+ <meta name="generator" content="sphinx-5.0.1, furo 2022.06.04.1"/>
9
9
  <title>Data types - Koffi</title>
10
10
  <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
11
11
  <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=40978830699223671f4072448e654b5958f38b89" />
@@ -498,9 +498,9 @@
498
498
  </table>
499
499
  </div>
500
500
  <p>Primitive types can be specified by name (in a string) or through <code class="docutils literal notranslate"><span class="pre">koffi.types</span></code>:</p>
501
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="c1">// These two lines do the same:</span><span class="w"></span>
502
- <span class="linenos">2</span><span class="kd">let</span><span class="w"> </span><span class="nx">struct1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">({</span><span class="w"> </span><span class="nx">dummy</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;int&#39;</span><span class="w"> </span><span class="p">});</span><span class="w"></span>
503
- <span class="linenos">3</span><span class="kd">let</span><span class="w"> </span><span class="nx">struct2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">({</span><span class="w"> </span><span class="nx">dummy</span><span class="o">:</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">types</span><span class="p">.</span><span class="kr">long</span><span class="w"> </span><span class="p">});</span><span class="w"></span>
501
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="c1">// These two lines do the same:</span>
502
+ <span class="linenos">2</span><span class="kd">let</span> <span class="nx">struct1</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">({</span> <span class="nx">dummy</span><span class="o">:</span> <span class="s1">&#39;long&#39;</span> <span class="p">});</span>
503
+ <span class="linenos">3</span><span class="kd">let</span> <span class="nx">struct2</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">({</span> <span class="nx">dummy</span><span class="o">:</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">types</span><span class="p">.</span><span class="kr">long</span> <span class="p">});</span>
504
504
  </pre></div>
505
505
  </div>
506
506
  </section>
@@ -520,22 +520,22 @@
520
520
  <span class="linenos">9</span><span class="p">}</span><span class="w"> </span><span class="n">A</span><span class="p">;</span><span class="w"></span>
521
521
  </pre></div>
522
522
  </div>
523
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span><span class="w"> </span><span class="nx">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;A&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
524
- <span class="linenos">2</span><span class="w"> </span><span class="nx">a</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;int&#39;</span><span class="p">,</span><span class="w"></span>
525
- <span class="linenos">3</span><span class="w"> </span><span class="nx">b</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;char&#39;</span><span class="p">,</span><span class="w"></span>
526
- <span class="linenos">4</span><span class="w"> </span><span class="nx">c</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;str&#39;</span><span class="p">,</span><span class="w"></span>
527
- <span class="linenos">5</span><span class="w"> </span><span class="nx">d</span><span class="o">:</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">({</span><span class="w"></span>
528
- <span class="linenos">6</span><span class="w"> </span><span class="nx">d1</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;double&#39;</span><span class="p">,</span><span class="w"></span>
529
- <span class="linenos">7</span><span class="w"> </span><span class="nx">d2</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;double&#39;</span><span class="w"></span>
530
- <span class="linenos">8</span><span class="w"> </span><span class="p">})</span><span class="w"></span>
531
- <span class="linenos">9</span><span class="p">});</span><span class="w"></span>
523
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span> <span class="nx">A</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="p">{</span>
524
+ <span class="linenos">2</span> <span class="nx">a</span><span class="o">:</span> <span class="s1">&#39;int&#39;</span><span class="p">,</span>
525
+ <span class="linenos">3</span> <span class="nx">b</span><span class="o">:</span> <span class="s1">&#39;char&#39;</span><span class="p">,</span>
526
+ <span class="linenos">4</span> <span class="nx">c</span><span class="o">:</span> <span class="s1">&#39;const char *&#39;</span><span class="p">,</span> <span class="c1">// Koffi does not care about const, it is ignored</span>
527
+ <span class="linenos">5</span> <span class="nx">d</span><span class="o">:</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">({</span>
528
+ <span class="linenos">6</span> <span class="nx">d1</span><span class="o">:</span> <span class="s1">&#39;double&#39;</span><span class="p">,</span>
529
+ <span class="linenos">7</span> <span class="nx">d2</span><span class="o">:</span> <span class="s1">&#39;double&#39;</span>
530
+ <span class="linenos">8</span> <span class="p">})</span>
531
+ <span class="linenos">9</span><span class="p">});</span>
532
532
  </pre></div>
533
533
  </div>
534
534
  <p>Koffi follows the C and ABI rules regarding struct alignment and padding.</p>
535
535
  <p>Once a struct is declared, you can use it by name (with a string, like you can do for primitive types) or through the value returned by the call to <code class="docutils literal notranslate"><span class="pre">koffi.struct()</span></code>. Only the latter is possible when declaring an anonymous struct.</p>
536
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="c1">// The following two function declarations are equivalent, and declare a function taking an A value and returning A</span><span class="w"></span>
537
- <span class="linenos">2</span><span class="kd">const</span><span class="w"> </span><span class="nx">Function1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;A Function(A value)&#39;</span><span class="p">);</span><span class="w"></span>
538
- <span class="linenos">3</span><span class="kd">const</span><span class="w"> </span><span class="nx">Function2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Function&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">A</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="nx">A</span><span class="p">]);</span><span class="w"></span>
536
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="c1">// The following two function declarations are equivalent, and declare a function taking an A value and returning A</span>
537
+ <span class="linenos">2</span><span class="kd">const</span> <span class="nx">Function1</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;A Function(A value)&#39;</span><span class="p">);</span>
538
+ <span class="linenos">3</span><span class="kd">const</span> <span class="nx">Function2</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Function&#39;</span><span class="p">,</span> <span class="nx">A</span><span class="p">,</span> <span class="p">[</span><span class="nx">A</span><span class="p">]);</span>
539
539
  </pre></div>
540
540
  </div>
541
541
  </section>
@@ -551,30 +551,36 @@
551
551
  <section id="struct-pointers">
552
552
  <h3>Struct pointers<a class="headerlink" href="#struct-pointers" title="Permalink to this heading">#</a></h3>
553
553
  <p>The following Win32 example uses <code class="docutils literal notranslate"><span class="pre">GetCursorPos()</span></code> (with an output parameter) to retrieve and show the current cursor position.</p>
554
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span><span class="w"> </span><span class="nx">koffi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span><span class="w"></span>
555
- <span class="linenos"> 2</span><span class="kd">const</span><span class="w"> </span><span class="nx">lib</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;kernel32.dll&#39;</span><span class="p">);</span><span class="w"></span>
554
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span> <span class="nx">koffi</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span>
555
+ <span class="linenos"> 2</span><span class="kd">const</span> <span class="nx">lib</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;kernel32.dll&#39;</span><span class="p">);</span>
556
556
  <span class="linenos"> 3</span>
557
- <span class="linenos"> 4</span><span class="c1">// Type declarations</span><span class="w"></span>
558
- <span class="linenos"> 5</span><span class="kd">const</span><span class="w"> </span><span class="nx">POINT</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;POINT&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
559
- <span class="linenos"> 6</span><span class="w"> </span><span class="nx">x</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;long&#39;</span><span class="p">,</span><span class="w"></span>
560
- <span class="linenos"> 7</span><span class="w"> </span><span class="nx">y</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;long&#39;</span><span class="w"></span>
561
- <span class="linenos"> 8</span><span class="p">});</span><span class="w"></span>
557
+ <span class="linenos"> 4</span><span class="c1">// Type declarations</span>
558
+ <span class="linenos"> 5</span><span class="kd">const</span> <span class="nx">POINT</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;POINT&#39;</span><span class="p">,</span> <span class="p">{</span>
559
+ <span class="linenos"> 6</span> <span class="nx">x</span><span class="o">:</span> <span class="s1">&#39;long&#39;</span><span class="p">,</span>
560
+ <span class="linenos"> 7</span> <span class="nx">y</span><span class="o">:</span> <span class="s1">&#39;long&#39;</span>
561
+ <span class="linenos"> 8</span><span class="p">});</span>
562
562
  <span class="linenos"> 9</span>
563
- <span class="linenos">10</span><span class="c1">// Functions declarations</span><span class="w"></span>
564
- <span class="linenos">11</span><span class="kd">const</span><span class="w"> </span><span class="nx">GetCursorPos</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;int __stdcall GetCursorPos(_Out_ POINT *pos)&#39;</span><span class="p">);</span><span class="w"></span>
563
+ <span class="linenos">10</span><span class="c1">// Functions declarations</span>
564
+ <span class="linenos">11</span><span class="kd">const</span> <span class="nx">GetCursorPos</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;int __stdcall GetCursorPos(_Out_ POINT *pos)&#39;</span><span class="p">);</span>
565
565
  <span class="linenos">12</span>
566
- <span class="linenos">13</span><span class="c1">// Get and show cursor position</span><span class="w"></span>
567
- <span class="linenos">14</span><span class="kd">let</span><span class="w"> </span><span class="nx">pos</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{};</span><span class="w"></span>
568
- <span class="linenos">15</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">GetCursorPos</span><span class="p">(</span><span class="nx">pos</span><span class="p">))</span><span class="w"></span>
569
- <span class="linenos">16</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Failed to get cursor position&#39;</span><span class="p">);</span><span class="w"></span>
570
- <span class="linenos">17</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">pos</span><span class="p">);</span><span class="w"></span>
566
+ <span class="linenos">13</span><span class="c1">// Get and show cursor position</span>
567
+ <span class="linenos">14</span><span class="kd">let</span> <span class="nx">pos</span> <span class="o">=</span> <span class="p">{};</span>
568
+ <span class="linenos">15</span><span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">GetCursorPos</span><span class="p">(</span><span class="nx">pos</span><span class="p">))</span>
569
+ <span class="linenos">16</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Failed to get cursor position&#39;</span><span class="p">);</span>
570
+ <span class="linenos">17</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">pos</span><span class="p">);</span>
571
571
  </pre></div>
572
572
  </div>
573
573
  </section>
574
574
  <section id="opaque-handles">
575
575
  <h3>Opaque handles<a class="headerlink" href="#opaque-handles" title="Permalink to this heading">#</a></h3>
576
576
  <p>Many C libraries use some kind of object-oriented API, with a pair of functions dedicated to create and delete objects. An obvious example of this can be found in stdio.h, with the opaque <code class="docutils literal notranslate"><span class="pre">FILE</span> <span class="pre">*</span></code> pointer. You can open and close files with <code class="docutils literal notranslate"><span class="pre">fopen()</span></code> and <code class="docutils literal notranslate"><span class="pre">fclose()</span></code>, and manipule the handle with other functions such as <code class="docutils literal notranslate"><span class="pre">fread()</span></code> or <code class="docutils literal notranslate"><span class="pre">ftell()</span></code>.</p>
577
- <p>In Koffi, you can manage this with opaque handles. Declare the handle type with <code class="docutils literal notranslate"><span class="pre">koffi.handle(name)</span></code>, and use this type either as a return type or some kind of <a class="reference internal" href="functions#output-parameters"><span class="std std-doc">output parameter</span></a> (with a pointer to the handle).</p>
577
+ <p>In Koffi, you can manage this with opaque handles. Declare the handle type with <code class="docutils literal notranslate"><span class="pre">koffi.handle(name)</span></code>, and use a pointer to this type either as a return type or some kind of <a class="reference internal" href="functions#output-parameters"><span class="std std-doc">output parameter</span></a> (with a double pointer).</p>
578
+ <div class="admonition note">
579
+ <p class="admonition-title">Note</p>
580
+ <p>Opaque handles <strong>have changed in version 2.0</strong>.</p>
581
+ <p>In Koffi 1.x, opaque handles were defined in a way that made them usable directly as parameter and return types, obscuring the underlying pointer.</p>
582
+ <p>Now, you must use them through a pointer, and use an array for output parameters. This is shown in the example below (look for the call to <code class="docutils literal notranslate"><span class="pre">ConcatNewOut</span></code> in the JS part), and is described in the section on <a class="reference internal" href="functions#output-parameters"><span class="std std-doc">output parameters</span></a>.</p>
583
+ </div>
578
584
  <p>The full example below implements an iterative string builder (concatenator) in C, and uses it from Javascript to output a mix of Hello World and FizzBuzz. The builder is hidden behind an opaque handle, and is created and destroyed using a pair of C functions: <code class="docutils literal notranslate"><span class="pre">ConcatNew</span></code> (or <code class="docutils literal notranslate"><span class="pre">ConcatNewOut</span></code>) and <code class="docutils literal notranslate"><span class="pre">ConcatFree</span></code>.</p>
579
585
  <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="c1">// Build with: clang -fPIC -o handles.so -shared handles.c -Wall -O2</span>
580
586
  <span class="linenos"> 2</span>
@@ -694,54 +700,56 @@
694
700
  <span class="linenos">116</span><span class="p">}</span><span class="w"></span>
695
701
  </pre></div>
696
702
  </div>
697
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span><span class="w"> </span><span class="nx">koffi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span><span class="w"></span>
698
- <span class="linenos"> 2</span><span class="kd">const</span><span class="w"> </span><span class="nx">lib</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;./handles.so&#39;</span><span class="p">);</span><span class="w"></span>
703
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span> <span class="nx">koffi</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span>
704
+ <span class="linenos"> 2</span><span class="kd">const</span> <span class="nx">lib</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;./handles.so&#39;</span><span class="p">);</span>
699
705
  <span class="linenos"> 3</span>
700
- <span class="linenos"> 4</span><span class="kd">const</span><span class="w"> </span><span class="nx">Concat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">handle</span><span class="p">(</span><span class="s1">&#39;Concat&#39;</span><span class="p">);</span><span class="w"></span>
701
- <span class="linenos"> 5</span><span class="kd">const</span><span class="w"> </span><span class="nx">ConcatNew</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Concat ConcatNew()&#39;</span><span class="p">);</span><span class="w"></span>
702
- <span class="linenos"> 6</span><span class="kd">const</span><span class="w"> </span><span class="nx">ConcatFree</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;void ConcatFree(Concat c)&#39;</span><span class="p">);</span><span class="w"></span>
703
- <span class="linenos"> 7</span><span class="kd">const</span><span class="w"> </span><span class="nx">ConcatAppend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool ConcatAppend(Concat c, const char *frag)&#39;</span><span class="p">);</span><span class="w"></span>
704
- <span class="linenos"> 8</span><span class="kd">const</span><span class="w"> </span><span class="nx">ConcatBuild</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;const char *ConcatBuild(Concat c)&#39;</span><span class="p">);</span><span class="w"></span>
705
- <span class="linenos"> 9</span><span class="kd">const</span><span class="w"> </span><span class="nx">ConcatNewOut</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool ConcatNewOut(_Out_ Concat out)&#39;</span><span class="p">);</span><span class="w"></span>
706
+ <span class="linenos"> 4</span><span class="kd">const</span> <span class="nx">Concat</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">handle</span><span class="p">(</span><span class="s1">&#39;Concat&#39;</span><span class="p">);</span>
707
+ <span class="linenos"> 5</span><span class="kd">const</span> <span class="nx">ConcatNewOut</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool ConcatNewOut(_Out_ Concat **out)&#39;</span><span class="p">);</span>
708
+ <span class="linenos"> 6</span><span class="kd">const</span> <span class="nx">ConcatNew</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Concat *ConcatNew()&#39;</span><span class="p">);</span>
709
+ <span class="linenos"> 7</span><span class="kd">const</span> <span class="nx">ConcatFree</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;void ConcatFree(Concat *c)&#39;</span><span class="p">);</span>
710
+ <span class="linenos"> 8</span><span class="kd">const</span> <span class="nx">ConcatAppend</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool ConcatAppend(Concat *c, const char *frag)&#39;</span><span class="p">);</span>
711
+ <span class="linenos"> 9</span><span class="kd">const</span> <span class="nx">ConcatBuild</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;const char *ConcatBuild(Concat *c)&#39;</span><span class="p">);</span>
706
712
  <span class="linenos">10</span>
707
- <span class="linenos">11</span><span class="kd">let</span><span class="w"> </span><span class="nx">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">ConcatNew</span><span class="p">();</span><span class="w"></span>
708
- <span class="linenos">12</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">c</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
709
- <span class="linenos">13</span><span class="w"> </span><span class="c1">// This is stupid, it does the same, but try both versions (return value, output parameter)</span><span class="w"></span>
710
- <span class="linenos">14</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">ConcatNewOut</span><span class="p">(</span><span class="nx">c</span><span class="p">))</span><span class="w"></span>
711
- <span class="linenos">15</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span><span class="w"></span>
712
- <span class="linenos">16</span><span class="p">}</span><span class="w"></span>
713
- <span class="linenos">17</span>
714
- <span class="linenos">18</span><span class="k">try</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
715
- <span class="linenos">19</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;Hello... &#39;</span><span class="p">))</span><span class="w"></span>
716
- <span class="linenos">20</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span><span class="w"></span>
717
- <span class="linenos">21</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;World!\n&#39;</span><span class="p">))</span><span class="w"></span>
718
- <span class="linenos">22</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span><span class="w"></span>
719
- <span class="linenos">23</span>
720
- <span class="linenos">24</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">let</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="mf">30</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
721
- <span class="linenos">25</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">frag</span><span class="p">;</span><span class="w"></span>
722
- <span class="linenos">26</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="mf">15</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
723
- <span class="linenos">27</span><span class="w"> </span><span class="nx">frag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;FizzBuzz&#39;</span><span class="p">;</span><span class="w"></span>
724
- <span class="linenos">28</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="mf">5</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
725
- <span class="linenos">29</span><span class="w"> </span><span class="nx">frag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;Buzz&#39;</span><span class="p">;</span><span class="w"></span>
726
- <span class="linenos">30</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="mf">3</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
727
- <span class="linenos">31</span><span class="w"> </span><span class="nx">frag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;Fizz&#39;</span><span class="p">;</span><span class="w"></span>
728
- <span class="linenos">32</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
729
- <span class="linenos">33</span><span class="w"> </span><span class="nx">frag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">String</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span><span class="w"></span>
730
- <span class="linenos">34</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
731
- <span class="linenos">35</span>
732
- <span class="linenos">36</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span><span class="w"> </span><span class="nx">frag</span><span class="p">))</span><span class="w"></span>
733
- <span class="linenos">37</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span><span class="w"></span>
734
- <span class="linenos">38</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39; &#39;</span><span class="p">))</span><span class="w"></span>
735
- <span class="linenos">39</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span><span class="w"></span>
736
- <span class="linenos">40</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
737
- <span class="linenos">41</span>
738
- <span class="linenos">42</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">str</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">ConcatBuild</span><span class="p">(</span><span class="nx">c</span><span class="p">);</span><span class="w"></span>
739
- <span class="linenos">43</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">str</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"></span>
740
- <span class="linenos">44</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span><span class="w"></span>
741
- <span class="linenos">45</span><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">str</span><span class="p">);</span><span class="w"></span>
742
- <span class="linenos">46</span><span class="p">}</span><span class="w"> </span><span class="k">finally</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
743
- <span class="linenos">47</span><span class="w"> </span><span class="nx">ConcatFree</span><span class="p">(</span><span class="nx">c</span><span class="p">);</span><span class="w"></span>
744
- <span class="linenos">48</span><span class="p">}</span><span class="w"></span>
713
+ <span class="linenos">11</span><span class="kd">let</span> <span class="nx">c</span> <span class="o">=</span> <span class="nx">ConcatNew</span><span class="p">();</span>
714
+ <span class="linenos">12</span><span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">c</span><span class="p">)</span> <span class="p">{</span>
715
+ <span class="linenos">13</span> <span class="c1">// This is stupid, it does the same, but try both versions (return value, output parameter)</span>
716
+ <span class="linenos">14</span> <span class="kd">let</span> <span class="nx">ptr</span> <span class="o">=</span> <span class="p">[</span><span class="kc">null</span><span class="p">];</span>
717
+ <span class="linenos">15</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ConcatNewOut</span><span class="p">(</span><span class="nx">ptr</span><span class="p">))</span>
718
+ <span class="linenos">16</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
719
+ <span class="linenos">17</span> <span class="nx">c</span> <span class="o">=</span> <span class="nx">ptr</span><span class="p">[</span><span class="mf">0</span><span class="p">];</span>
720
+ <span class="linenos">18</span><span class="p">}</span>
721
+ <span class="linenos">19</span>
722
+ <span class="linenos">20</span><span class="k">try</span> <span class="p">{</span>
723
+ <span class="linenos">21</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span> <span class="s1">&#39;Hello... &#39;</span><span class="p">))</span>
724
+ <span class="linenos">22</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
725
+ <span class="linenos">23</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span> <span class="s1">&#39;World!\n&#39;</span><span class="p">))</span>
726
+ <span class="linenos">24</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
727
+ <span class="linenos">25</span>
728
+ <span class="linenos">26</span> <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mf">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="mf">30</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
729
+ <span class="linenos">27</span> <span class="kd">let</span> <span class="nx">frag</span><span class="p">;</span>
730
+ <span class="linenos">28</span> <span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mf">15</span> <span class="o">==</span> <span class="mf">0</span><span class="p">)</span> <span class="p">{</span>
731
+ <span class="linenos">29</span> <span class="nx">frag</span> <span class="o">=</span> <span class="s1">&#39;FizzBuzz&#39;</span><span class="p">;</span>
732
+ <span class="linenos">30</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mf">5</span> <span class="o">==</span> <span class="mf">0</span><span class="p">)</span> <span class="p">{</span>
733
+ <span class="linenos">31</span> <span class="nx">frag</span> <span class="o">=</span> <span class="s1">&#39;Buzz&#39;</span><span class="p">;</span>
734
+ <span class="linenos">32</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mf">3</span> <span class="o">==</span> <span class="mf">0</span><span class="p">)</span> <span class="p">{</span>
735
+ <span class="linenos">33</span> <span class="nx">frag</span> <span class="o">=</span> <span class="s1">&#39;Fizz&#39;</span><span class="p">;</span>
736
+ <span class="linenos">34</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
737
+ <span class="linenos">35</span> <span class="nx">frag</span> <span class="o">=</span> <span class="nb">String</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
738
+ <span class="linenos">36</span> <span class="p">}</span>
739
+ <span class="linenos">37</span>
740
+ <span class="linenos">38</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span> <span class="nx">frag</span><span class="p">))</span>
741
+ <span class="linenos">39</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
742
+ <span class="linenos">40</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span> <span class="s1">&#39; &#39;</span><span class="p">))</span>
743
+ <span class="linenos">41</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
744
+ <span class="linenos">42</span> <span class="p">}</span>
745
+ <span class="linenos">43</span>
746
+ <span class="linenos">44</span> <span class="kd">let</span> <span class="nx">str</span> <span class="o">=</span> <span class="nx">ConcatBuild</span><span class="p">(</span><span class="nx">c</span><span class="p">);</span>
747
+ <span class="linenos">45</span> <span class="k">if</span> <span class="p">(</span><span class="nx">str</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span>
748
+ <span class="linenos">46</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
749
+ <span class="linenos">47</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">str</span><span class="p">);</span>
750
+ <span class="linenos">48</span><span class="p">}</span> <span class="k">finally</span> <span class="p">{</span>
751
+ <span class="linenos">49</span> <span class="nx">ConcatFree</span><span class="p">(</span><span class="nx">c</span><span class="p">);</span>
752
+ <span class="linenos">50</span><span class="p">}</span>
745
753
  </pre></div>
746
754
  </div>
747
755
  </section>
@@ -769,77 +777,77 @@
769
777
  <span class="linenos">17</span><span class="p">}</span><span class="w"></span>
770
778
  </pre></div>
771
779
  </div>
772
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span><span class="w"> </span><span class="nx">koffi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span><span class="w"></span>
773
- <span class="linenos">2</span><span class="kd">const</span><span class="w"> </span><span class="nx">lib</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;./length.so&#39;</span><span class="p">);</span><span class="w"></span>
780
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span> <span class="nx">koffi</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span>
781
+ <span class="linenos">2</span><span class="kd">const</span> <span class="nx">lib</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;./length.so&#39;</span><span class="p">);</span>
774
782
  <span class="linenos">3</span>
775
- <span class="linenos">4</span><span class="kd">const</span><span class="w"> </span><span class="nx">ComputeTotalLength</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;int64_t ComputeTotalLength(const char **strings)&#39;</span><span class="p">);</span><span class="w"></span>
783
+ <span class="linenos">4</span><span class="kd">const</span> <span class="nx">ComputeTotalLength</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;int64_t ComputeTotalLength(const char **strings)&#39;</span><span class="p">);</span>
776
784
  <span class="linenos">5</span>
777
- <span class="linenos">6</span><span class="kd">let</span><span class="w"> </span><span class="nx">strings</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;Get&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;Total&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;Length&#39;</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">];</span><span class="w"></span>
778
- <span class="linenos">7</span><span class="kd">let</span><span class="w"> </span><span class="nx">total</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">ComputeTotalLength</span><span class="p">(</span><span class="nx">strings</span><span class="p">);</span><span class="w"></span>
785
+ <span class="linenos">6</span><span class="kd">let</span> <span class="nx">strings</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;Get&#39;</span><span class="p">,</span> <span class="s1">&#39;Total&#39;</span><span class="p">,</span> <span class="s1">&#39;Length&#39;</span><span class="p">,</span> <span class="kc">null</span><span class="p">];</span>
786
+ <span class="linenos">7</span><span class="kd">let</span> <span class="nx">total</span> <span class="o">=</span> <span class="nx">ComputeTotalLength</span><span class="p">(</span><span class="nx">strings</span><span class="p">);</span>
779
787
  <span class="linenos">8</span>
780
- <span class="linenos">9</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">total</span><span class="p">);</span><span class="w"> </span><span class="c1">// Prints 14</span><span class="w"></span>
788
+ <span class="linenos">9</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">total</span><span class="p">);</span> <span class="c1">// Prints 14</span>
781
789
  </pre></div>
782
790
  </div>
783
791
  <p>By default, just like for objects, array arguments are copied from JS to C but not vice-versa. You can however change the direction as documented in the section on <a class="reference internal" href="functions#output-parameters"><span class="std std-doc">output parameters</span></a>.</p>
784
792
  <p>Here is an example based on the Win32 API, listing files in the current directory with <code class="docutils literal notranslate"><span class="pre">FindFirstFileW()</span></code> and <code class="docutils literal notranslate"><span class="pre">FindNextFileW()</span></code>:</p>
785
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span><span class="w"> </span><span class="nx">koffi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span><span class="w"></span>
786
- <span class="linenos"> 2</span><span class="kd">const</span><span class="w"> </span><span class="nx">lib</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;kernel32.dll&#39;</span><span class="p">);</span><span class="w"></span>
793
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span> <span class="nx">koffi</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span>
794
+ <span class="linenos"> 2</span><span class="kd">const</span> <span class="nx">lib</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;kernel32.dll&#39;</span><span class="p">);</span>
787
795
  <span class="linenos"> 3</span>
788
- <span class="linenos"> 4</span><span class="kd">const</span><span class="w"> </span><span class="nx">HANDLE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">handle</span><span class="p">(</span><span class="s1">&#39;HANDLE&#39;</span><span class="p">);</span><span class="w"></span>
789
- <span class="linenos"> 5</span><span class="kd">const</span><span class="w"> </span><span class="nx">FILETIME</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;FILETIME&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
790
- <span class="linenos"> 6</span><span class="w"> </span><span class="nx">dwLowDateTime</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;uint&#39;</span><span class="p">,</span><span class="w"></span>
791
- <span class="linenos"> 7</span><span class="w"> </span><span class="nx">dwHighDateTime</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;uint&#39;</span><span class="w"></span>
792
- <span class="linenos"> 8</span><span class="p">});</span><span class="w"></span>
793
- <span class="linenos"> 9</span><span class="kd">const</span><span class="w"> </span><span class="nx">WIN32_FIND_DATA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;WIN32_FIND_DATA&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
794
- <span class="linenos">10</span><span class="w"> </span><span class="nx">dwFileAttributes</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;uint&#39;</span><span class="p">,</span><span class="w"></span>
795
- <span class="linenos">11</span><span class="w"> </span><span class="nx">ftCreationTime</span><span class="o">:</span><span class="w"> </span><span class="nx">FILETIME</span><span class="p">,</span><span class="w"></span>
796
- <span class="linenos">12</span><span class="w"> </span><span class="nx">ftLastAccessTime</span><span class="o">:</span><span class="w"> </span><span class="nx">FILETIME</span><span class="p">,</span><span class="w"></span>
797
- <span class="linenos">13</span><span class="w"> </span><span class="nx">ftLastWriteTime</span><span class="o">:</span><span class="w"> </span><span class="nx">FILETIME</span><span class="p">,</span><span class="w"></span>
798
- <span class="linenos">14</span><span class="w"> </span><span class="nx">nFileSizeHigh</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;uint&#39;</span><span class="p">,</span><span class="w"></span>
799
- <span class="linenos">15</span><span class="w"> </span><span class="nx">nFileSizeLow</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;uint&#39;</span><span class="p">,</span><span class="w"></span>
800
- <span class="linenos">16</span><span class="w"> </span><span class="nx">dwReserved0</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;uint&#39;</span><span class="p">,</span><span class="w"></span>
801
- <span class="linenos">17</span><span class="w"> </span><span class="nx">dwReserved1</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;uint&#39;</span><span class="p">,</span><span class="w"></span>
802
- <span class="linenos">18</span><span class="w"> </span><span class="nx">cFileName</span><span class="o">:</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">array</span><span class="p">(</span><span class="s1">&#39;char16&#39;</span><span class="p">,</span><span class="w"> </span><span class="mf">260</span><span class="p">),</span><span class="w"></span>
803
- <span class="linenos">19</span><span class="w"> </span><span class="nx">cAlternateFileName</span><span class="o">:</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">array</span><span class="p">(</span><span class="s1">&#39;char16&#39;</span><span class="p">,</span><span class="w"> </span><span class="mf">14</span><span class="p">),</span><span class="w"></span>
804
- <span class="linenos">20</span><span class="w"> </span><span class="nx">dwFileType</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;uint&#39;</span><span class="p">,</span><span class="w"> </span><span class="c1">// Obsolete. Do not use.</span><span class="w"></span>
805
- <span class="linenos">21</span><span class="w"> </span><span class="nx">dwCreatorType</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;uint&#39;</span><span class="p">,</span><span class="w"> </span><span class="c1">// Obsolete. Do not use</span><span class="w"></span>
806
- <span class="linenos">22</span><span class="w"> </span><span class="nx">wFinderFlags</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;ushort&#39;</span><span class="w"> </span><span class="c1">// Obsolete. Do not use</span><span class="w"></span>
807
- <span class="linenos">23</span><span class="p">});</span><span class="w"></span>
796
+ <span class="linenos"> 4</span><span class="kd">const</span> <span class="nx">HANDLE</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">pointer</span><span class="p">(</span><span class="s1">&#39;HANDLE&#39;</span><span class="p">,</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">handle</span><span class="p">());</span>
797
+ <span class="linenos"> 5</span><span class="kd">const</span> <span class="nx">FILETIME</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;FILETIME&#39;</span><span class="p">,</span> <span class="p">{</span>
798
+ <span class="linenos"> 6</span> <span class="nx">dwLowDateTime</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span><span class="p">,</span>
799
+ <span class="linenos"> 7</span> <span class="nx">dwHighDateTime</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span>
800
+ <span class="linenos"> 8</span><span class="p">});</span>
801
+ <span class="linenos"> 9</span><span class="kd">const</span> <span class="nx">WIN32_FIND_DATA</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;WIN32_FIND_DATA&#39;</span><span class="p">,</span> <span class="p">{</span>
802
+ <span class="linenos">10</span> <span class="nx">dwFileAttributes</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span><span class="p">,</span>
803
+ <span class="linenos">11</span> <span class="nx">ftCreationTime</span><span class="o">:</span> <span class="nx">FILETIME</span><span class="p">,</span>
804
+ <span class="linenos">12</span> <span class="nx">ftLastAccessTime</span><span class="o">:</span> <span class="nx">FILETIME</span><span class="p">,</span>
805
+ <span class="linenos">13</span> <span class="nx">ftLastWriteTime</span><span class="o">:</span> <span class="nx">FILETIME</span><span class="p">,</span>
806
+ <span class="linenos">14</span> <span class="nx">nFileSizeHigh</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span><span class="p">,</span>
807
+ <span class="linenos">15</span> <span class="nx">nFileSizeLow</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span><span class="p">,</span>
808
+ <span class="linenos">16</span> <span class="nx">dwReserved0</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span><span class="p">,</span>
809
+ <span class="linenos">17</span> <span class="nx">dwReserved1</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span><span class="p">,</span>
810
+ <span class="linenos">18</span> <span class="nx">cFileName</span><span class="o">:</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">array</span><span class="p">(</span><span class="s1">&#39;char16&#39;</span><span class="p">,</span> <span class="mf">260</span><span class="p">),</span>
811
+ <span class="linenos">19</span> <span class="nx">cAlternateFileName</span><span class="o">:</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">array</span><span class="p">(</span><span class="s1">&#39;char16&#39;</span><span class="p">,</span> <span class="mf">14</span><span class="p">),</span>
812
+ <span class="linenos">20</span> <span class="nx">dwFileType</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span><span class="p">,</span> <span class="c1">// Obsolete. Do not use.</span>
813
+ <span class="linenos">21</span> <span class="nx">dwCreatorType</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span><span class="p">,</span> <span class="c1">// Obsolete. Do not use</span>
814
+ <span class="linenos">22</span> <span class="nx">wFinderFlags</span><span class="o">:</span> <span class="s1">&#39;ushort&#39;</span> <span class="c1">// Obsolete. Do not use</span>
815
+ <span class="linenos">23</span><span class="p">});</span>
808
816
  <span class="linenos">24</span>
809
- <span class="linenos">25</span><span class="kd">const</span><span class="w"> </span><span class="nx">FindFirstFile</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;HANDLE __stdcall FindFirstFileW(str16 path, _Out_ WIN32_FIND_DATA *data)&#39;</span><span class="p">);</span><span class="w"></span>
810
- <span class="linenos">26</span><span class="kd">const</span><span class="w"> </span><span class="nx">FindNextFile</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool __stdcall FindNextFileW(HANDLE h, _Out_ WIN32_FIND_DATA *data)&#39;</span><span class="p">);</span><span class="w"></span>
811
- <span class="linenos">27</span><span class="kd">const</span><span class="w"> </span><span class="nx">FindClose</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool __stdcall FindClose(HANDLE h)&#39;</span><span class="p">);</span><span class="w"></span>
812
- <span class="linenos">28</span><span class="kd">const</span><span class="w"> </span><span class="nx">GetLastError</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;uint GetLastError()&#39;</span><span class="p">);</span><span class="w"></span>
817
+ <span class="linenos">25</span><span class="kd">const</span> <span class="nx">FindFirstFile</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;HANDLE __stdcall FindFirstFileW(str16 path, _Out_ WIN32_FIND_DATA *data)&#39;</span><span class="p">);</span>
818
+ <span class="linenos">26</span><span class="kd">const</span> <span class="nx">FindNextFile</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool __stdcall FindNextFileW(HANDLE h, _Out_ WIN32_FIND_DATA *data)&#39;</span><span class="p">);</span>
819
+ <span class="linenos">27</span><span class="kd">const</span> <span class="nx">FindClose</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool __stdcall FindClose(HANDLE h)&#39;</span><span class="p">);</span>
820
+ <span class="linenos">28</span><span class="kd">const</span> <span class="nx">GetLastError</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;uint GetLastError()&#39;</span><span class="p">);</span>
813
821
  <span class="linenos">29</span>
814
- <span class="linenos">30</span><span class="kd">function</span><span class="w"> </span><span class="nx">list</span><span class="p">(</span><span class="nx">dirname</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
815
- <span class="linenos">31</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">filenames</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[];</span><span class="w"></span>
822
+ <span class="linenos">30</span><span class="kd">function</span> <span class="nx">list</span><span class="p">(</span><span class="nx">dirname</span><span class="p">)</span> <span class="p">{</span>
823
+ <span class="linenos">31</span> <span class="kd">let</span> <span class="nx">filenames</span> <span class="o">=</span> <span class="p">[];</span>
816
824
  <span class="linenos">32</span>
817
- <span class="linenos">33</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{};</span><span class="w"></span>
818
- <span class="linenos">34</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">h</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">FindFirstFile</span><span class="p">(</span><span class="nx">dirname</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">&#39;\\*&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">data</span><span class="p">);</span><span class="w"></span>
825
+ <span class="linenos">33</span> <span class="kd">let</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">{};</span>
826
+ <span class="linenos">34</span> <span class="kd">let</span> <span class="nx">h</span> <span class="o">=</span> <span class="nx">FindFirstFile</span><span class="p">(</span><span class="nx">dirname</span> <span class="o">+</span> <span class="s1">&#39;\\*&#39;</span><span class="p">,</span> <span class="nx">data</span><span class="p">);</span>
819
827
  <span class="linenos">35</span>
820
- <span class="linenos">36</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">h</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
821
- <span class="linenos">37</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">GetLastError</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">2</span><span class="p">)</span><span class="w"> </span><span class="c1">// ERROR_FILE_NOT_FOUND</span><span class="w"></span>
822
- <span class="linenos">38</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">filenames</span><span class="p">;</span><span class="w"></span>
823
- <span class="linenos">39</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;FindFirstFile() failed&#39;</span><span class="p">);</span><span class="w"></span>
824
- <span class="linenos">40</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
828
+ <span class="linenos">36</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">h</span><span class="p">)</span> <span class="p">{</span>
829
+ <span class="linenos">37</span> <span class="k">if</span> <span class="p">(</span><span class="nx">GetLastError</span><span class="p">()</span> <span class="o">==</span> <span class="mf">2</span><span class="p">)</span> <span class="c1">// ERROR_FILE_NOT_FOUND</span>
830
+ <span class="linenos">38</span> <span class="k">return</span> <span class="nx">filenames</span><span class="p">;</span>
831
+ <span class="linenos">39</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;FindFirstFile() failed&#39;</span><span class="p">);</span>
832
+ <span class="linenos">40</span> <span class="p">}</span>
825
833
  <span class="linenos">41</span>
826
- <span class="linenos">42</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
827
- <span class="linenos">43</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
828
- <span class="linenos">44</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">cFileName</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="s1">&#39;.&#39;</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">data</span><span class="p">.</span><span class="nx">cFileName</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="s1">&#39;..&#39;</span><span class="p">)</span><span class="w"></span>
829
- <span class="linenos">45</span><span class="w"> </span><span class="nx">filenames</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">cFileName</span><span class="p">);</span><span class="w"></span>
830
- <span class="linenos">46</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="nx">FindNextFile</span><span class="p">(</span><span class="nx">h</span><span class="p">,</span><span class="w"> </span><span class="nx">data</span><span class="p">));</span><span class="w"></span>
834
+ <span class="linenos">42</span> <span class="k">try</span> <span class="p">{</span>
835
+ <span class="linenos">43</span> <span class="k">do</span> <span class="p">{</span>
836
+ <span class="linenos">44</span> <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">cFileName</span> <span class="o">!=</span> <span class="s1">&#39;.&#39;</span> <span class="o">&amp;&amp;</span> <span class="nx">data</span><span class="p">.</span><span class="nx">cFileName</span> <span class="o">!=</span> <span class="s1">&#39;..&#39;</span><span class="p">)</span>
837
+ <span class="linenos">45</span> <span class="nx">filenames</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">cFileName</span><span class="p">);</span>
838
+ <span class="linenos">46</span> <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="nx">FindNextFile</span><span class="p">(</span><span class="nx">h</span><span class="p">,</span> <span class="nx">data</span><span class="p">));</span>
831
839
  <span class="linenos">47</span>
832
- <span class="linenos">48</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">GetLastError</span><span class="p">()</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mf">18</span><span class="p">)</span><span class="w"> </span><span class="c1">// ERROR_NO_MORE_FILES</span><span class="w"></span>
833
- <span class="linenos">49</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;FindNextFile() failed&#39;</span><span class="p">);</span><span class="w"></span>
834
- <span class="linenos">50</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">finally</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
835
- <span class="linenos">51</span><span class="w"> </span><span class="nx">FindClose</span><span class="p">(</span><span class="nx">h</span><span class="p">);</span><span class="w"></span>
836
- <span class="linenos">52</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
840
+ <span class="linenos">48</span> <span class="k">if</span> <span class="p">(</span><span class="nx">GetLastError</span><span class="p">()</span> <span class="o">!=</span> <span class="mf">18</span><span class="p">)</span> <span class="c1">// ERROR_NO_MORE_FILES</span>
841
+ <span class="linenos">49</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;FindNextFile() failed&#39;</span><span class="p">);</span>
842
+ <span class="linenos">50</span> <span class="p">}</span> <span class="k">finally</span> <span class="p">{</span>
843
+ <span class="linenos">51</span> <span class="nx">FindClose</span><span class="p">(</span><span class="nx">h</span><span class="p">);</span>
844
+ <span class="linenos">52</span> <span class="p">}</span>
837
845
  <span class="linenos">53</span>
838
- <span class="linenos">54</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">filenames</span><span class="p">;</span><span class="w"></span>
839
- <span class="linenos">55</span><span class="p">}</span><span class="w"></span>
846
+ <span class="linenos">54</span> <span class="k">return</span> <span class="nx">filenames</span><span class="p">;</span>
847
+ <span class="linenos">55</span><span class="p">}</span>
840
848
  <span class="linenos">56</span>
841
- <span class="linenos">57</span><span class="kd">let</span><span class="w"> </span><span class="nx">filenames</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">list</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">);</span><span class="w"></span>
842
- <span class="linenos">58</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">filenames</span><span class="p">);</span><span class="w"></span>
849
+ <span class="linenos">57</span><span class="kd">let</span> <span class="nx">filenames</span> <span class="o">=</span> <span class="nx">list</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">);</span>
850
+ <span class="linenos">58</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">filenames</span><span class="p">);</span>
843
851
  </pre></div>
844
852
  </div>
845
853
  </section>
@@ -847,12 +855,12 @@
847
855
  <h3>Pointers to primitive types<a class="headerlink" href="#pointers-to-primitive-types" title="Permalink to this heading">#</a></h3>
848
856
  <p>In javascript, it is not possible to pass a primitive value by reference to another function. This means that you cannot call a function and expect it to modify the value of one of its number or string parameter.</p>
849
857
  <p>However, arrays and objects (among others) are reference type values. Assigning an array or an object from one variable to another does not invole any copy. Instead, as the following example illustrates, the new variable references the same array as the first:</p>
850
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">let</span><span class="w"> </span><span class="nx">list1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mf">1</span><span class="p">,</span><span class="w"> </span><span class="mf">2</span><span class="p">];</span><span class="w"></span>
851
- <span class="linenos">2</span><span class="kd">let</span><span class="w"> </span><span class="nx">list2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">list1</span><span class="p">;</span><span class="w"></span>
858
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">let</span> <span class="nx">list1</span> <span class="o">=</span> <span class="p">[</span><span class="mf">1</span><span class="p">,</span> <span class="mf">2</span><span class="p">];</span>
859
+ <span class="linenos">2</span><span class="kd">let</span> <span class="nx">list2</span> <span class="o">=</span> <span class="nx">list1</span><span class="p">;</span>
852
860
  <span class="linenos">3</span>
853
- <span class="linenos">4</span><span class="nx">list2</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">42</span><span class="p">;</span><span class="w"></span>
861
+ <span class="linenos">4</span><span class="nx">list2</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span> <span class="o">=</span> <span class="mf">42</span><span class="p">;</span>
854
862
  <span class="linenos">5</span>
855
- <span class="linenos">6</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">list1</span><span class="p">);</span><span class="w"> </span><span class="c1">// Prints [1, 42]</span><span class="w"></span>
863
+ <span class="linenos">6</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">list1</span><span class="p">);</span> <span class="c1">// Prints [1, 42]</span>
856
864
  </pre></div>
857
865
  </div>
858
866
  <p>All of this means that C functions that are expected to modify their primitive output values (such as an <code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">*</span></code> parameter) cannot be used directly. However, thanks to Koffi’s transparent array support, you can use Javascript arrays to approximate reference semantics with single-element arrays.</p>
@@ -864,12 +872,12 @@
864
872
  </pre></div>
865
873
  </div>
866
874
  <p>You can simply pass a single-element array as the first argument:</p>
867
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span><span class="w"> </span><span class="nx">AddInt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;void AddInt(_Inout_ int *dest, int add)&#39;</span><span class="p">);</span><span class="w"></span>
875
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span> <span class="nx">AddInt</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;void AddInt(_Inout_ int *dest, int add)&#39;</span><span class="p">);</span>
868
876
  <span class="linenos">2</span>
869
- <span class="linenos">3</span><span class="kd">let</span><span class="w"> </span><span class="nx">sum</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mf">36</span><span class="p">];</span><span class="w"></span>
870
- <span class="linenos">4</span><span class="nx">AddInt</span><span class="p">(</span><span class="nx">sum</span><span class="p">,</span><span class="w"> </span><span class="mf">6</span><span class="p">);</span><span class="w"></span>
877
+ <span class="linenos">3</span><span class="kd">let</span> <span class="nx">sum</span> <span class="o">=</span> <span class="p">[</span><span class="mf">36</span><span class="p">];</span>
878
+ <span class="linenos">4</span><span class="nx">AddInt</span><span class="p">(</span><span class="nx">sum</span><span class="p">,</span> <span class="mf">6</span><span class="p">);</span>
871
879
  <span class="linenos">5</span>
872
- <span class="linenos">6</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">sum</span><span class="p">[</span><span class="mf">0</span><span class="p">]);</span><span class="w"> </span><span class="c1">// Prints 42</span><span class="w"></span>
880
+ <span class="linenos">6</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">sum</span><span class="p">[</span><span class="mf">0</span><span class="p">]);</span> <span class="c1">// Prints 42</span>
873
881
  </pre></div>
874
882
  </div>
875
883
  </section>
@@ -883,24 +891,24 @@
883
891
  <li><p><strong>C to JS</strong> (return value, output parameters, callbacks): Koffi will use a TypedArray if possible. But you can change this behavior when you create the array type with the optional hint argument: <code class="docutils literal notranslate"><span class="pre">koffi.array('uint8_t',</span> <span class="pre">64,</span> <span class="pre">'array')</span></code>. For non-number types, such as arrays of strings or structs, Koffi creates normal arrays.</p></li>
884
892
  </ul>
885
893
  <p>See the example below:</p>
886
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span><span class="w"> </span><span class="nx">koffi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span><span class="w"></span>
894
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span> <span class="nx">koffi</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span>
887
895
  <span class="linenos"> 2</span>
888
- <span class="linenos"> 3</span><span class="c1">// Those two structs are exactly the same, only the array conversion hint is different</span><span class="w"></span>
889
- <span class="linenos"> 4</span><span class="kd">const</span><span class="w"> </span><span class="nx">Foo1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;Foo&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
890
- <span class="linenos"> 5</span><span class="w"> </span><span class="nx">i</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;int&#39;</span><span class="p">,</span><span class="w"></span>
891
- <span class="linenos"> 6</span><span class="w"> </span><span class="nx">a16</span><span class="o">:</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">array</span><span class="p">(</span><span class="s1">&#39;int16_t&#39;</span><span class="p">,</span><span class="w"> </span><span class="mf">8</span><span class="p">)</span><span class="w"></span>
892
- <span class="linenos"> 7</span><span class="p">});</span><span class="w"></span>
893
- <span class="linenos"> 8</span><span class="kd">const</span><span class="w"> </span><span class="nx">Foo2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;Foo&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
894
- <span class="linenos"> 9</span><span class="w"> </span><span class="nx">i</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;int&#39;</span><span class="p">,</span><span class="w"></span>
895
- <span class="linenos">10</span><span class="w"> </span><span class="nx">a16</span><span class="o">:</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">array</span><span class="p">(</span><span class="s1">&#39;int16_t&#39;</span><span class="p">,</span><span class="w"> </span><span class="mf">8</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;array&#39;</span><span class="p">)</span><span class="w"></span>
896
- <span class="linenos">11</span><span class="p">});</span><span class="w"></span>
896
+ <span class="linenos"> 3</span><span class="c1">// Those two structs are exactly the same, only the array conversion hint is different</span>
897
+ <span class="linenos"> 4</span><span class="kd">const</span> <span class="nx">Foo1</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;Foo&#39;</span><span class="p">,</span> <span class="p">{</span>
898
+ <span class="linenos"> 5</span> <span class="nx">i</span><span class="o">:</span> <span class="s1">&#39;int&#39;</span><span class="p">,</span>
899
+ <span class="linenos"> 6</span> <span class="nx">a16</span><span class="o">:</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">array</span><span class="p">(</span><span class="s1">&#39;int16_t&#39;</span><span class="p">,</span> <span class="mf">8</span><span class="p">)</span>
900
+ <span class="linenos"> 7</span><span class="p">});</span>
901
+ <span class="linenos"> 8</span><span class="kd">const</span> <span class="nx">Foo2</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;Foo&#39;</span><span class="p">,</span> <span class="p">{</span>
902
+ <span class="linenos"> 9</span> <span class="nx">i</span><span class="o">:</span> <span class="s1">&#39;int&#39;</span><span class="p">,</span>
903
+ <span class="linenos">10</span> <span class="nx">a16</span><span class="o">:</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">array</span><span class="p">(</span><span class="s1">&#39;int16_t&#39;</span><span class="p">,</span> <span class="mf">8</span><span class="p">,</span> <span class="s1">&#39;array&#39;</span><span class="p">)</span>
904
+ <span class="linenos">11</span><span class="p">});</span>
897
905
  <span class="linenos">12</span>
898
- <span class="linenos">13</span><span class="c1">// Uses an hypothetical C function that just returns the struct passed as a parameter</span><span class="w"></span>
899
- <span class="linenos">14</span><span class="kd">const</span><span class="w"> </span><span class="nx">ReturnFoo1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Foo1 ReturnFoo(Foo1 p)&#39;</span><span class="p">);</span><span class="w"></span>
900
- <span class="linenos">15</span><span class="kd">const</span><span class="w"> </span><span class="nx">ReturnFoo2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Foo2 ReturnFoo(Foo2 p)&#39;</span><span class="p">);</span><span class="w"></span>
906
+ <span class="linenos">13</span><span class="c1">// Uses an hypothetical C function that just returns the struct passed as a parameter</span>
907
+ <span class="linenos">14</span><span class="kd">const</span> <span class="nx">ReturnFoo1</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Foo1 ReturnFoo(Foo1 p)&#39;</span><span class="p">);</span>
908
+ <span class="linenos">15</span><span class="kd">const</span> <span class="nx">ReturnFoo2</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Foo2 ReturnFoo(Foo2 p)&#39;</span><span class="p">);</span>
901
909
  <span class="linenos">16</span>
902
- <span class="linenos">17</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">ReturnFoo1</span><span class="p">({</span><span class="w"> </span><span class="nx">i</span><span class="o">:</span><span class="w"> </span><span class="mf">5</span><span class="p">,</span><span class="w"> </span><span class="nx">a16</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="mf">6</span><span class="p">,</span><span class="w"> </span><span class="mf">8</span><span class="p">]</span><span class="w"> </span><span class="p">}))</span><span class="w"> </span><span class="c1">// Prints { i: 5, a16: Int16Array(2) [6, 8] }</span><span class="w"></span>
903
- <span class="linenos">18</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">ReturnFoo2</span><span class="p">({</span><span class="w"> </span><span class="nx">i</span><span class="o">:</span><span class="w"> </span><span class="mf">5</span><span class="p">,</span><span class="w"> </span><span class="nx">a16</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="mf">6</span><span class="p">,</span><span class="w"> </span><span class="mf">8</span><span class="p">]</span><span class="w"> </span><span class="p">}))</span><span class="w"> </span><span class="c1">// Prints { i: 5, a16: [6, 8] }</span><span class="w"></span>
910
+ <span class="linenos">17</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">ReturnFoo1</span><span class="p">({</span> <span class="nx">i</span><span class="o">:</span> <span class="mf">5</span><span class="p">,</span> <span class="nx">a16</span><span class="o">:</span> <span class="p">[</span><span class="mf">6</span><span class="p">,</span> <span class="mf">8</span><span class="p">]</span> <span class="p">}))</span> <span class="c1">// Prints { i: 5, a16: Int16Array(2) [6, 8] }</span>
911
+ <span class="linenos">18</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">ReturnFoo2</span><span class="p">({</span> <span class="nx">i</span><span class="o">:</span> <span class="mf">5</span><span class="p">,</span> <span class="nx">a16</span><span class="o">:</span> <span class="p">[</span><span class="mf">6</span><span class="p">,</span> <span class="mf">8</span><span class="p">]</span> <span class="p">}))</span> <span class="c1">// Prints { i: 5, a16: [6, 8] }</span>
904
912
  </pre></div>
905
913
  </div>
906
914
  <section id="handling-of-strings">
@@ -919,12 +927,17 @@
919
927
  <ul class="simple">
920
928
  <li><p><code class="docutils literal notranslate"><span class="pre">koffi.sizeof(type)</span></code> to get the size of a type</p></li>
921
929
  <li><p><code class="docutils literal notranslate"><span class="pre">koffi.alignof(type)</span></code> to get the alignment of a type</p></li>
922
- <li><p><code class="docutils literal notranslate"><span class="pre">koffi.introspect(type)</span></code> to get the definition of a type (only for structs for now)</p></li>
930
+ <li><p><code class="docutils literal notranslate"><span class="pre">koffi.introspect(type)</span></code> to get the definition of a type in an object containing: name, primitive, size, alignment, members (structs), reference (array, pointer) and length (array)</p></li>
923
931
  </ul>
932
+ <div class="admonition note">
933
+ <p class="admonition-title">Note</p>
934
+ <p>The value returned by <code class="docutils literal notranslate"><span class="pre">introspect()</span></code> has <strong>changed in version 2.0</strong>.</p>
935
+ <p>In Koffi 1.x, it could only be used with struct types and returned the object passed to koffi.struct() with the member names and types.</p>
936
+ </div>
924
937
  <p>Just like before, you can refer to primitive types by their name or through <code class="docutils literal notranslate"><span class="pre">koffi.types</span></code>:</p>
925
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="c1">// These two lines do the same:</span><span class="w"></span>
926
- <span class="linenos">2</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">koffi</span><span class="p">.</span><span class="nx">sizeof</span><span class="p">(</span><span class="s1">&#39;long&#39;</span><span class="p">));</span><span class="w"></span>
927
- <span class="linenos">3</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">koffi</span><span class="p">.</span><span class="nx">sizeof</span><span class="p">(</span><span class="nx">koffi</span><span class="p">.</span><span class="nx">types</span><span class="p">.</span><span class="kr">long</span><span class="p">));</span><span class="w"></span>
938
+ <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="c1">// These two lines do the same:</span>
939
+ <span class="linenos">2</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">koffi</span><span class="p">.</span><span class="nx">sizeof</span><span class="p">(</span><span class="s1">&#39;long&#39;</span><span class="p">));</span>
940
+ <span class="linenos">3</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">koffi</span><span class="p">.</span><span class="nx">sizeof</span><span class="p">(</span><span class="nx">koffi</span><span class="p">.</span><span class="nx">types</span><span class="p">.</span><span class="kr">long</span><span class="p">));</span>
928
941
  </pre></div>
929
942
  </div>
930
943
  </section>