koffi 1.2.4 → 1.3.0-rc.1
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.
- package/README.md +7 -489
- package/benchmark/CMakeLists.txt +13 -9
- package/benchmark/raylib_node_raylib.js +67 -0
- package/build/qemu/1.3.0-rc.1/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.0-rc.1/koffi_win32_x64.tar.gz +0 -0
- package/doc/Makefile +20 -0
- package/doc/_static/bench_linux.png +0 -0
- package/doc/_static/bench_windows.png +0 -0
- package/doc/_static/custom.css +22 -0
- package/doc/benchmarks.md +113 -0
- package/doc/benchmarks.xlsx +0 -0
- package/doc/conf.py +54 -0
- package/doc/contribute.md +115 -0
- package/doc/dist/doctrees/benchmarks.doctree +0 -0
- package/doc/dist/doctrees/contribute.doctree +0 -0
- package/doc/dist/doctrees/environment.pickle +0 -0
- package/doc/dist/doctrees/functions.doctree +0 -0
- package/doc/dist/doctrees/index.doctree +0 -0
- package/doc/dist/doctrees/memory.doctree +0 -0
- package/doc/dist/doctrees/platforms.doctree +0 -0
- package/doc/dist/doctrees/start.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/dist/html/.buildinfo +4 -0
- package/doc/dist/html/_sources/benchmarks.md.txt +113 -0
- package/doc/dist/html/_sources/contribute.md.txt +115 -0
- package/doc/dist/html/_sources/functions.md.txt +224 -0
- package/doc/dist/html/_sources/index.rst.txt +33 -0
- package/doc/dist/html/_sources/memory.md.txt +29 -0
- package/doc/dist/html/_sources/platforms.md.txt +17 -0
- package/doc/dist/html/_sources/start.md.txt +89 -0
- package/doc/dist/html/_sources/types.md.txt +514 -0
- package/doc/dist/html/_static/_sphinx_javascript_frameworks_compat.js +134 -0
- package/doc/dist/html/_static/basic.css +932 -0
- package/doc/dist/html/_static/bench_linux.png +0 -0
- package/doc/dist/html/_static/bench_windows.png +0 -0
- package/doc/dist/html/_static/custom.css +22 -0
- package/doc/dist/html/_static/debug.css +69 -0
- package/doc/dist/html/_static/doctools.js +264 -0
- package/doc/dist/html/_static/documentation_options.js +14 -0
- package/doc/dist/html/_static/file.png +0 -0
- package/doc/dist/html/_static/jquery-3.6.0.js +10881 -0
- package/doc/dist/html/_static/jquery.js +2 -0
- package/doc/dist/html/_static/language_data.js +199 -0
- package/doc/dist/html/_static/minus.png +0 -0
- package/doc/dist/html/_static/plus.png +0 -0
- package/doc/dist/html/_static/pygments.css +252 -0
- package/doc/dist/html/_static/scripts/furo-extensions.js +0 -0
- package/doc/dist/html/_static/scripts/furo.js +3 -0
- package/doc/dist/html/_static/scripts/furo.js.LICENSE.txt +7 -0
- package/doc/dist/html/_static/scripts/furo.js.map +1 -0
- package/doc/dist/html/_static/searchtools.js +531 -0
- package/doc/dist/html/_static/skeleton.css +296 -0
- package/doc/dist/html/_static/styles/furo-extensions.css +2 -0
- package/doc/dist/html/_static/styles/furo-extensions.css.map +1 -0
- package/doc/dist/html/_static/styles/furo.css +2 -0
- package/doc/dist/html/_static/styles/furo.css.map +1 -0
- package/doc/dist/html/_static/underscore-1.13.1.js +2042 -0
- package/doc/dist/html/_static/underscore.js +6 -0
- package/doc/dist/html/benchmarks.html +547 -0
- package/doc/dist/html/contribute.html +382 -0
- package/doc/dist/html/functions.html +530 -0
- package/doc/dist/html/genindex.html +249 -0
- package/doc/dist/html/index.html +342 -0
- package/doc/dist/html/memory.html +337 -0
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +332 -0
- package/doc/dist/html/search.html +257 -0
- package/doc/dist/html/searchindex.js +1 -0
- package/doc/dist/html/start.html +367 -0
- package/doc/dist/html/types.html +1001 -0
- package/doc/functions.md +224 -0
- package/doc/index.rst +33 -0
- package/doc/make.bat +35 -0
- package/doc/memory.md +29 -0
- package/doc/platforms.md +17 -0
- package/doc/start.md +89 -0
- package/doc/types.md +514 -0
- package/package.json +5 -2
- package/qemu/qemu.js +41 -27
- package/qemu/registry/machines.json +59 -79
- package/qemu/registry/sha256sum.txt +4 -4
- package/src/abi_arm32.cc +20 -48
- package/src/abi_arm64.cc +18 -46
- package/src/abi_arm64_fwd.S +5 -0
- package/src/abi_riscv64.cc +19 -47
- package/src/abi_x64_sysv.cc +18 -46
- package/src/abi_x64_win.cc +19 -47
- package/src/abi_x86.cc +21 -49
- package/src/call.cc +505 -242
- package/src/call.hh +14 -7
- package/src/ffi.cc +47 -26
- package/src/ffi.hh +1 -1
- package/src/parser.cc +2 -20
- package/src/util.cc +50 -11
- package/src/util.hh +2 -0
- package/test/misc.c +31 -0
- package/test/sync.js +41 -4
- package/benchmark/atoi_cc.cc +0 -59
- package/build/qemu/1.2.4/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_linux_riscv64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.2.4/koffi_win32_x64.tar.gz +0 -0
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html class="no-js" lang="en">
|
|
3
|
+
<head><meta charset="utf-8"/>
|
|
4
|
+
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
5
|
+
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
|
|
6
|
+
<link rel="index" title="Index" href="genindex" /><link rel="search" title="Search" href="search" /><link rel="next" title="Memory usage" href="memory" /><link rel="prev" title="Data types" href="types" />
|
|
7
|
+
|
|
8
|
+
<meta name="generator" content="sphinx-5.0.1, furo 2022.06.04.1"/>
|
|
9
|
+
<title>Function calls - Koffi</title>
|
|
10
|
+
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
|
11
|
+
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=40978830699223671f4072448e654b5958f38b89" />
|
|
12
|
+
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
|
|
13
|
+
<link rel="stylesheet" type="text/css" href="_static/custom.css" />
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
<style>
|
|
19
|
+
body {
|
|
20
|
+
--color-code-background: #f8f8f8;
|
|
21
|
+
--color-code-foreground: black;
|
|
22
|
+
--color-brand-primary: #FF6600;
|
|
23
|
+
--color-brand-content: #FF6600;
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
@media not print {
|
|
27
|
+
body[data-theme="dark"] {
|
|
28
|
+
--color-code-background: #202020;
|
|
29
|
+
--color-code-foreground: #d0d0d0;
|
|
30
|
+
--color-brand-primary: #FF6600;
|
|
31
|
+
--color-brand-content: #FF6600;
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
@media (prefers-color-scheme: dark) {
|
|
35
|
+
body:not([data-theme="light"]) {
|
|
36
|
+
--color-code-background: #202020;
|
|
37
|
+
--color-code-foreground: #d0d0d0;
|
|
38
|
+
--color-brand-primary: #FF6600;
|
|
39
|
+
--color-brand-content: #FF6600;
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
</style></head>
|
|
45
|
+
<body>
|
|
46
|
+
|
|
47
|
+
<script>
|
|
48
|
+
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
|
53
|
+
<symbol id="svg-toc" viewBox="0 0 24 24">
|
|
54
|
+
<title>Contents</title>
|
|
55
|
+
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
|
|
56
|
+
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
|
|
57
|
+
</svg>
|
|
58
|
+
</symbol>
|
|
59
|
+
<symbol id="svg-menu" viewBox="0 0 24 24">
|
|
60
|
+
<title>Menu</title>
|
|
61
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
62
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
|
|
63
|
+
<line x1="3" y1="12" x2="21" y2="12"></line>
|
|
64
|
+
<line x1="3" y1="6" x2="21" y2="6"></line>
|
|
65
|
+
<line x1="3" y1="18" x2="21" y2="18"></line>
|
|
66
|
+
</svg>
|
|
67
|
+
</symbol>
|
|
68
|
+
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
|
|
69
|
+
<title>Expand</title>
|
|
70
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
71
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
|
|
72
|
+
<polyline points="9 18 15 12 9 6"></polyline>
|
|
73
|
+
</svg>
|
|
74
|
+
</symbol>
|
|
75
|
+
<symbol id="svg-sun" viewBox="0 0 24 24">
|
|
76
|
+
<title>Light mode</title>
|
|
77
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
78
|
+
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
|
|
79
|
+
<circle cx="12" cy="12" r="5"></circle>
|
|
80
|
+
<line x1="12" y1="1" x2="12" y2="3"></line>
|
|
81
|
+
<line x1="12" y1="21" x2="12" y2="23"></line>
|
|
82
|
+
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
|
83
|
+
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
|
84
|
+
<line x1="1" y1="12" x2="3" y2="12"></line>
|
|
85
|
+
<line x1="21" y1="12" x2="23" y2="12"></line>
|
|
86
|
+
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
|
87
|
+
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
|
88
|
+
</svg>
|
|
89
|
+
</symbol>
|
|
90
|
+
<symbol id="svg-moon" viewBox="0 0 24 24">
|
|
91
|
+
<title>Dark mode</title>
|
|
92
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
93
|
+
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
|
|
94
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
95
|
+
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
|
|
96
|
+
</svg>
|
|
97
|
+
</symbol>
|
|
98
|
+
<symbol id="svg-sun-half" viewBox="0 0 24 24">
|
|
99
|
+
<title>Auto light/dark mode</title>
|
|
100
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
101
|
+
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-shadow">
|
|
102
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
|
103
|
+
<circle cx="12" cy="12" r="9" />
|
|
104
|
+
<path d="M13 12h5" />
|
|
105
|
+
<path d="M13 15h4" />
|
|
106
|
+
<path d="M13 18h1" />
|
|
107
|
+
<path d="M13 9h4" />
|
|
108
|
+
<path d="M13 6h1" />
|
|
109
|
+
</svg>
|
|
110
|
+
</symbol>
|
|
111
|
+
</svg>
|
|
112
|
+
|
|
113
|
+
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
|
|
114
|
+
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc">
|
|
115
|
+
<label class="overlay sidebar-overlay" for="__navigation">
|
|
116
|
+
<div class="visually-hidden">Hide navigation sidebar</div>
|
|
117
|
+
</label>
|
|
118
|
+
<label class="overlay toc-overlay" for="__toc">
|
|
119
|
+
<div class="visually-hidden">Hide table of contents sidebar</div>
|
|
120
|
+
</label>
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
<div class="page">
|
|
125
|
+
<header class="mobile-header">
|
|
126
|
+
<div class="header-left">
|
|
127
|
+
<label class="nav-overlay-icon" for="__navigation">
|
|
128
|
+
<div class="visually-hidden">Toggle site navigation sidebar</div>
|
|
129
|
+
<i class="icon"><svg><use href="#svg-menu"></use></svg></i>
|
|
130
|
+
</label>
|
|
131
|
+
</div>
|
|
132
|
+
<div class="header-center">
|
|
133
|
+
<a href="index"><div class="brand">Koffi</div></a>
|
|
134
|
+
</div>
|
|
135
|
+
<div class="header-right">
|
|
136
|
+
<div class="theme-toggle-container theme-toggle-header">
|
|
137
|
+
<button class="theme-toggle">
|
|
138
|
+
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
|
139
|
+
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
|
140
|
+
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
|
141
|
+
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
|
142
|
+
</button>
|
|
143
|
+
</div>
|
|
144
|
+
<label class="toc-overlay-icon toc-header-icon" for="__toc">
|
|
145
|
+
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
|
146
|
+
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
|
147
|
+
</label>
|
|
148
|
+
</div>
|
|
149
|
+
</header>
|
|
150
|
+
<aside class="sidebar-drawer">
|
|
151
|
+
<div class="sidebar-container">
|
|
152
|
+
|
|
153
|
+
<div class="sidebar-sticky"><a class="sidebar-brand" href="index">
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
<span class="sidebar-brand-text">Koffi</span>
|
|
157
|
+
|
|
158
|
+
</a><form class="sidebar-search-container" method="get" action="search" role="search">
|
|
159
|
+
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
|
160
|
+
<input type="hidden" name="check_keywords" value="yes">
|
|
161
|
+
<input type="hidden" name="area" value="default">
|
|
162
|
+
</form>
|
|
163
|
+
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
|
164
|
+
<ul class="current">
|
|
165
|
+
<li class="toctree-l1"><a class="reference internal" href="platforms">Supported platforms</a></li>
|
|
166
|
+
<li class="toctree-l1"><a class="reference internal" href="start">Quick start</a></li>
|
|
167
|
+
<li class="toctree-l1"><a class="reference internal" href="types">Data types</a></li>
|
|
168
|
+
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">Function calls</a></li>
|
|
169
|
+
<li class="toctree-l1"><a class="reference internal" href="memory">Memory usage</a></li>
|
|
170
|
+
<li class="toctree-l1"><a class="reference internal" href="benchmarks">Benchmarks</a></li>
|
|
171
|
+
<li class="toctree-l1"><a class="reference internal" href="contribute">Contributing</a></li>
|
|
172
|
+
</ul>
|
|
173
|
+
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
</div>
|
|
180
|
+
</aside>
|
|
181
|
+
<div class="main">
|
|
182
|
+
<div class="content">
|
|
183
|
+
<div class="article-container">
|
|
184
|
+
<a href="#" class="back-to-top muted-link">
|
|
185
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
186
|
+
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
|
|
187
|
+
</svg>
|
|
188
|
+
<span>Back to top</span>
|
|
189
|
+
</a>
|
|
190
|
+
<div class="content-icon-container">
|
|
191
|
+
<div class="theme-toggle-container theme-toggle-content">
|
|
192
|
+
<button class="theme-toggle">
|
|
193
|
+
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
|
194
|
+
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
|
195
|
+
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
|
196
|
+
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
|
197
|
+
</button>
|
|
198
|
+
</div>
|
|
199
|
+
<label class="toc-overlay-icon toc-content-icon" for="__toc">
|
|
200
|
+
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
|
201
|
+
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
|
202
|
+
</label>
|
|
203
|
+
</div>
|
|
204
|
+
<article role="main">
|
|
205
|
+
<section id="function-calls">
|
|
206
|
+
<h1>Function calls<a class="headerlink" href="#function-calls" title="Permalink to this heading">#</a></h1>
|
|
207
|
+
<section id="function-definitions">
|
|
208
|
+
<h2>Function definitions<a class="headerlink" href="#function-definitions" title="Permalink to this heading">#</a></h2>
|
|
209
|
+
<p>To declare functions, start by loading the shared library with <code class="docutils literal notranslate"><span class="pre">koffi.load()</span></code>.</p>
|
|
210
|
+
<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">'koffi'</span><span class="p">);</span>
|
|
211
|
+
<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">'/path/to/shared/library'</span><span class="p">);</span> <span class="c1">// File extension depends on platforms: .so, .dll, .dylib, etc.</span>
|
|
212
|
+
</pre></div>
|
|
213
|
+
</div>
|
|
214
|
+
<p>You can use the returned object to load C functions from the library. Koffi supports two syntaxes:</p>
|
|
215
|
+
<ul class="simple">
|
|
216
|
+
<li><p>Classic syntax, inspired by node-ffi</p></li>
|
|
217
|
+
<li><p>C-like prototypes</p></li>
|
|
218
|
+
</ul>
|
|
219
|
+
<section id="classic-syntax">
|
|
220
|
+
<h3>Classic syntax<a class="headerlink" href="#classic-syntax" title="Permalink to this heading">#</a></h3>
|
|
221
|
+
<p>To declare a function, you need to specify its non-mangled name, its return type, and its parameters. Use an ellipsis as the last parameter for variadic functions.</p>
|
|
222
|
+
<div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span> <span class="nx">printf</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">'printf'</span><span class="p">,</span> <span class="s1">'int'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'string'</span><span class="p">,</span> <span class="s1">'...'</span><span class="p">]);</span>
|
|
223
|
+
<span class="linenos">2</span><span class="kd">const</span> <span class="nx">atoi</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">'atoi'</span><span class="p">,</span> <span class="s1">'int'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'string'</span><span class="p">]);</span>
|
|
224
|
+
</pre></div>
|
|
225
|
+
</div>
|
|
226
|
+
<p>Koffi automatically tries mangled names for non-standard x86 calling conventions. See the section <a class="reference internal" href="#synchronous-calls"><span class="std std-doc">on standard calls</span></a> for more information on this subject.</p>
|
|
227
|
+
</section>
|
|
228
|
+
<section id="c-like-prototypes">
|
|
229
|
+
<h3>C-like prototypes<a class="headerlink" href="#c-like-prototypes" title="Permalink to this heading">#</a></h3>
|
|
230
|
+
<p>You can declare functions using simple C-like prototype strings, as shown below:</p>
|
|
231
|
+
<div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span> <span class="nx">printf</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">'int printf(const char *fmt, ...)'</span><span class="p">);</span>
|
|
232
|
+
<span class="linenos">2</span><span class="kd">const</span> <span class="nx">atoi</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">'int atoi(string)'</span><span class="p">);</span> <span class="c1">// The parameter name is not used by Koffi, and optional</span>
|
|
233
|
+
</pre></div>
|
|
234
|
+
</div>
|
|
235
|
+
</section>
|
|
236
|
+
</section>
|
|
237
|
+
<section id="synchronous-calls">
|
|
238
|
+
<h2>Synchronous calls<a class="headerlink" href="#synchronous-calls" title="Permalink to this heading">#</a></h2>
|
|
239
|
+
<p>By default, calling a C function happens synchronously.</p>
|
|
240
|
+
<p>Most architectures only support one procedure call standard per process. The 32-bit x86 platform is an exception to this, and Koffi support several standards:</p>
|
|
241
|
+
<div class="table-wrapper colwidths-auto docutils container">
|
|
242
|
+
<table class="docutils align-default">
|
|
243
|
+
<thead>
|
|
244
|
+
<tr class="row-odd"><th class="head"><p>Convention</p></th>
|
|
245
|
+
<th class="head"><p>Classic form</p></th>
|
|
246
|
+
<th class="head"><p>Prototype form</p></th>
|
|
247
|
+
<th class="head"><p>Description</p></th>
|
|
248
|
+
</tr>
|
|
249
|
+
</thead>
|
|
250
|
+
<tbody>
|
|
251
|
+
<tr class="row-even"><td><p><strong>Cdecl</strong></p></td>
|
|
252
|
+
<td><p><code class="docutils literal notranslate"><span class="pre">koffi.cdecl</span></code> or <code class="docutils literal notranslate"><span class="pre">koffi.func</span></code></p></td>
|
|
253
|
+
<td><p><em>(default)</em></p></td>
|
|
254
|
+
<td><p>This is the default convention, and the only one on other platforms</p></td>
|
|
255
|
+
</tr>
|
|
256
|
+
<tr class="row-odd"><td><p><strong>Stdcall</strong></p></td>
|
|
257
|
+
<td><p><code class="docutils literal notranslate"><span class="pre">koffi.stdcall</span></code></p></td>
|
|
258
|
+
<td><p>__stdcall</p></td>
|
|
259
|
+
<td><p>This convention is used extensively within the Win32 API</p></td>
|
|
260
|
+
</tr>
|
|
261
|
+
<tr class="row-even"><td><p><strong>Fastcall</strong></p></td>
|
|
262
|
+
<td><p><code class="docutils literal notranslate"><span class="pre">koffi.fastcall</span></code></p></td>
|
|
263
|
+
<td><p>__fastcall</p></td>
|
|
264
|
+
<td><p>Rarely used, uses ECX and EDX for first two parameters</p></td>
|
|
265
|
+
</tr>
|
|
266
|
+
<tr class="row-odd"><td><p><strong>Thiscall</strong></p></td>
|
|
267
|
+
<td><p><code class="docutils literal notranslate"><span class="pre">koffi.thiscall</span></code></p></td>
|
|
268
|
+
<td><p>__thiscall</p></td>
|
|
269
|
+
<td><p>Rarely used, uses ECX for first parameter</p></td>
|
|
270
|
+
</tr>
|
|
271
|
+
</tbody>
|
|
272
|
+
</table>
|
|
273
|
+
</div>
|
|
274
|
+
<p>You can safely use these on non-x86 platforms, they are simply ignored.</p>
|
|
275
|
+
<p>Below you can find a small example showing how to use a non-default calling convention:</p>
|
|
276
|
+
<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">'koffi'</span><span class="p">);</span>
|
|
277
|
+
<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">'user32.dll'</span><span class="p">);</span>
|
|
278
|
+
<span class="linenos">3</span>
|
|
279
|
+
<span class="linenos">4</span><span class="c1">// The following two declarations are equivalent, and use Stdcall</span>
|
|
280
|
+
<span class="linenos">5</span><span class="kd">const</span> <span class="nx">MessageBoxA_1</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">stdcall</span><span class="p">(</span><span class="s1">'MessageBoxA'</span><span class="p">,</span> <span class="s1">'int'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'void *'</span><span class="p">,</span> <span class="s1">'string'</span><span class="p">,</span> <span class="s1">'string'</span><span class="p">,</span> <span class="s1">'uint'</span><span class="p">]);</span>
|
|
281
|
+
<span class="linenos">6</span><span class="kd">const</span> <span class="nx">MessageBoxA_2</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">'int __stdcall MessageBoxA(void *hwnd, string text, string caption, uint type)'</span><span class="p">);</span>
|
|
282
|
+
</pre></div>
|
|
283
|
+
</div>
|
|
284
|
+
</section>
|
|
285
|
+
<section id="asynchronous-calls">
|
|
286
|
+
<h2>Asynchronous calls<a class="headerlink" href="#asynchronous-calls" title="Permalink to this heading">#</a></h2>
|
|
287
|
+
<p>You can issue asynchronous calls by calling the function through its async member. In this case, you need to provide a callback function as the last argument, with <code class="docutils literal notranslate"><span class="pre">(err,</span> <span class="pre">res)</span></code> parameters.</p>
|
|
288
|
+
<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">'koffi'</span><span class="p">);</span>
|
|
289
|
+
<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">'libc.so.6'</span><span class="p">);</span>
|
|
290
|
+
<span class="linenos"> 3</span>
|
|
291
|
+
<span class="linenos"> 4</span><span class="kd">const</span> <span class="nx">atoi</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">'int atoi(const char *str)'</span><span class="p">);</span>
|
|
292
|
+
<span class="linenos"> 5</span>
|
|
293
|
+
<span class="linenos"> 6</span><span class="nx">atoi</span><span class="p">.</span><span class="k">async</span><span class="p">(</span><span class="s1">'1257'</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=></span> <span class="p">{</span>
|
|
294
|
+
<span class="linenos"> 7</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Result:'</span><span class="p">,</span> <span class="nx">res</span><span class="p">);</span>
|
|
295
|
+
<span class="linenos"> 8</span><span class="p">})</span>
|
|
296
|
+
<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="s1">'Hello World!'</span><span class="p">);</span>
|
|
297
|
+
<span class="linenos">10</span>
|
|
298
|
+
<span class="linenos">11</span><span class="c1">// This program will print "Hello World!", and then "Result: 1257"</span>
|
|
299
|
+
</pre></div>
|
|
300
|
+
</div>
|
|
301
|
+
<p>You can easily convert this callback-style async function to a promise-based version with <code class="docutils literal notranslate"><span class="pre">util.promisify()</span></code> from the Node.js standard library.</p>
|
|
302
|
+
<p>Variadic functions cannot be called asynchronously.</p>
|
|
303
|
+
</section>
|
|
304
|
+
<section id="variadic-functions">
|
|
305
|
+
<h2>Variadic functions<a class="headerlink" href="#variadic-functions" title="Permalink to this heading">#</a></h2>
|
|
306
|
+
<p>Variadic functions are declared with an ellipsis as the last argument.</p>
|
|
307
|
+
<p>In order to call a variadic function, you must provide two Javascript arguments for each additional C parameter, the first one is the expected type and the second one is the value.</p>
|
|
308
|
+
<div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span> <span class="nx">printf</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">'printf'</span><span class="p">,</span> <span class="s1">'int'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'string'</span><span class="p">,</span> <span class="s1">'...'</span><span class="p">]);</span>
|
|
309
|
+
<span class="linenos">2</span>
|
|
310
|
+
<span class="linenos">3</span><span class="c1">// The variadic arguments are: 6 (int), 8.5 (double), 'THE END' (const char *)</span>
|
|
311
|
+
<span class="linenos">4</span><span class="nx">printf</span><span class="p">(</span><span class="s1">'Integer %d, double %g, string %s'</span><span class="p">,</span> <span class="s1">'int'</span><span class="p">,</span> <span class="mf">6</span><span class="p">,</span> <span class="s1">'double'</span><span class="p">,</span> <span class="mf">8.5</span><span class="p">,</span> <span class="s1">'string'</span><span class="p">,</span> <span class="s1">'THE END'</span><span class="p">);</span>
|
|
312
|
+
</pre></div>
|
|
313
|
+
</div>
|
|
314
|
+
<p>On x86 platforms, only the Cdecl convention can be used for variadic functions.</p>
|
|
315
|
+
</section>
|
|
316
|
+
<section id="output-parameters">
|
|
317
|
+
<h2>Output parameters<a class="headerlink" href="#output-parameters" title="Permalink to this heading">#</a></h2>
|
|
318
|
+
<p>By default, Koffi will only forward arguments from Javascript to C. However, many C functions use pointer arguments for output values, or input/output values.</p>
|
|
319
|
+
<p>For simplicy, and because Javascript only has value semantics for primitive types, Koffi can marshal out (or in/out) two types of parameters:</p>
|
|
320
|
+
<ul class="simple">
|
|
321
|
+
<li><p><a class="reference internal" href="types#struct-types"><span class="std std-doc">Structs</span></a> (to/from JS objects)</p></li>
|
|
322
|
+
<li><p><a class="reference internal" href="types#opaque-handles"><span class="std std-doc">Opaque handles</span></a></p></li>
|
|
323
|
+
</ul>
|
|
324
|
+
<p>In order to change an argument from input-only to output or input/output, use the following functions:</p>
|
|
325
|
+
<ul class="simple">
|
|
326
|
+
<li><p><code class="docutils literal notranslate"><span class="pre">koffi.out()</span></code> on a pointer, e.g. <code class="docutils literal notranslate"><span class="pre">koffi.out(koffi.pointer(timeval))</span></code> (where timeval is a struct type)</p></li>
|
|
327
|
+
<li><p><code class="docutils literal notranslate"><span class="pre">koffi.inout()</span></code> for dual input/output parameters</p></li>
|
|
328
|
+
</ul>
|
|
329
|
+
<p>The same can be done when declaring a function with a C-like prototype string, with the MSDN-like type qualifiers:</p>
|
|
330
|
+
<ul class="simple">
|
|
331
|
+
<li><p><code class="docutils literal notranslate"><span class="pre">_Out_</span></code> for output parameters</p></li>
|
|
332
|
+
<li><p><code class="docutils literal notranslate"><span class="pre">_Inout_</span></code> for dual input/output parameters</p></li>
|
|
333
|
+
</ul>
|
|
334
|
+
<section id="struct-example">
|
|
335
|
+
<h3>Struct example<a class="headerlink" href="#struct-example" title="Permalink to this heading">#</a></h3>
|
|
336
|
+
<p>This example calls the POSIX function <code class="docutils literal notranslate"><span class="pre">gettimeofday()</span></code>, and uses the prototype-like syntax.</p>
|
|
337
|
+
<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">'koffi'</span><span class="p">);</span>
|
|
338
|
+
<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">'libc.so.6'</span><span class="p">);</span>
|
|
339
|
+
<span class="linenos"> 3</span>
|
|
340
|
+
<span class="linenos"> 4</span><span class="kd">const</span> <span class="nx">timeval</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">'timeval'</span><span class="p">,</span> <span class="p">{</span>
|
|
341
|
+
<span class="linenos"> 5</span> <span class="nx">tv_sec</span><span class="o">:</span> <span class="s1">'unsigned int'</span><span class="p">,</span>
|
|
342
|
+
<span class="linenos"> 6</span> <span class="nx">tv_usec</span><span class="o">:</span> <span class="s1">'unsigned int'</span>
|
|
343
|
+
<span class="linenos"> 7</span><span class="p">});</span>
|
|
344
|
+
<span class="linenos"> 8</span><span class="kd">const</span> <span class="nx">timezone</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">'timezone'</span><span class="p">,</span> <span class="p">{</span>
|
|
345
|
+
<span class="linenos"> 9</span> <span class="nx">tz_minuteswest</span><span class="o">:</span> <span class="s1">'int'</span><span class="p">,</span>
|
|
346
|
+
<span class="linenos">10</span> <span class="nx">tz_dsttime</span><span class="o">:</span> <span class="s1">'int'</span>
|
|
347
|
+
<span class="linenos">11</span><span class="p">});</span>
|
|
348
|
+
<span class="linenos">12</span>
|
|
349
|
+
<span class="linenos">13</span><span class="c1">// The _Out_ qualifiers instruct Koffi to marshal out the values</span>
|
|
350
|
+
<span class="linenos">14</span><span class="kd">const</span> <span class="nx">gettimeofday</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">'int gettimeofday(_Out_ timeval *tv, _Out_ timezone *tz)'</span><span class="p">);</span>
|
|
351
|
+
<span class="linenos">15</span>
|
|
352
|
+
<span class="linenos">16</span><span class="kd">let</span> <span class="nx">tv</span> <span class="o">=</span> <span class="p">{};</span>
|
|
353
|
+
<span class="linenos">17</span><span class="nx">gettimeofday</span><span class="p">(</span><span class="nx">tv</span><span class="p">,</span> <span class="kc">null</span><span class="p">);</span>
|
|
354
|
+
<span class="linenos">18</span>
|
|
355
|
+
<span class="linenos">19</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">tv</span><span class="p">);</span>
|
|
356
|
+
</pre></div>
|
|
357
|
+
</div>
|
|
358
|
+
</section>
|
|
359
|
+
<section id="opaque-handle-example">
|
|
360
|
+
<h3>Opaque handle example<a class="headerlink" href="#opaque-handle-example" title="Permalink to this heading">#</a></h3>
|
|
361
|
+
<p>This example opens an in-memory SQLite database, and uses the node-ffi-style function declaration syntax.</p>
|
|
362
|
+
<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">'koffi'</span><span class="p">);</span>
|
|
363
|
+
<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">'sqlite.so'</span><span class="p">);</span>
|
|
364
|
+
<span class="linenos"> 3</span>
|
|
365
|
+
<span class="linenos"> 4</span><span class="kd">const</span> <span class="nx">sqlite3_db</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">'sqlite3_db'</span><span class="p">);</span>
|
|
366
|
+
<span class="linenos"> 5</span>
|
|
367
|
+
<span class="linenos"> 6</span><span class="c1">// Use koffi.out() on a pointer to copy out (from C to JS) after the call</span>
|
|
368
|
+
<span class="linenos"> 7</span><span class="kd">const</span> <span class="nx">sqlite3_open_v2</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">'sqlite3_open_v2'</span><span class="p">,</span> <span class="s1">'int'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'string'</span><span class="p">,</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">out</span><span class="p">(</span><span class="nx">koffi</span><span class="p">.</span><span class="nx">pointer</span><span class="p">(</span><span class="nx">sqlite3_db</span><span class="p">)),</span> <span class="s1">'int'</span><span class="p">,</span> <span class="s1">'string'</span><span class="p">]);</span>
|
|
369
|
+
<span class="linenos"> 8</span>
|
|
370
|
+
<span class="linenos"> 9</span><span class="kd">const</span> <span class="nx">SQLITE_OPEN_READWRITE</span> <span class="o">=</span> <span class="mh">0x2</span><span class="p">;</span>
|
|
371
|
+
<span class="linenos">10</span><span class="kd">const</span> <span class="nx">SQLITE_OPEN_CREATE</span> <span class="o">=</span> <span class="mh">0x4</span><span class="p">;</span>
|
|
372
|
+
<span class="linenos">11</span>
|
|
373
|
+
<span class="linenos">12</span><span class="kd">let</span> <span class="nx">db</span> <span class="o">=</span> <span class="p">{};</span>
|
|
374
|
+
<span class="linenos">13</span><span class="k">if</span> <span class="p">(</span><span class="nx">sqlite3_open_v2</span><span class="p">(</span><span class="s1">':memory:'</span><span class="p">,</span> <span class="nx">db</span><span class="p">,</span> <span class="nx">SQLITE_OPEN_READWRITE</span> <span class="o">|</span> <span class="nx">SQLITE_OPEN_CREATE</span><span class="p">,</span> <span class="kc">null</span><span class="p">)</span> <span class="o">!=</span> <span class="mf">0</span><span class="p">)</span>
|
|
375
|
+
<span class="linenos">14</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">'Failed to open database'</span><span class="p">);</span>
|
|
376
|
+
<span class="linenos">15</span><span class="nx">sqlite3_close_v2</span><span class="p">(</span><span class="nx">db</span><span class="p">);</span>
|
|
377
|
+
</pre></div>
|
|
378
|
+
</div>
|
|
379
|
+
</section>
|
|
380
|
+
</section>
|
|
381
|
+
<section id="javascript-callbacks">
|
|
382
|
+
<h2>Javascript callbacks<a class="headerlink" href="#javascript-callbacks" title="Permalink to this heading">#</a></h2>
|
|
383
|
+
<section id="using-callbacks">
|
|
384
|
+
<h3>Using callbacks<a class="headerlink" href="#using-callbacks" title="Permalink to this heading">#</a></h3>
|
|
385
|
+
<p>In order to pass a JS function to a C function expecting a callback, you must first create a callback type with the expected return type and parameters. The syntax is similar to the one used to load functions from a shared library.</p>
|
|
386
|
+
<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">'koffi'</span><span class="p">);</span>
|
|
387
|
+
<span class="linenos">2</span>
|
|
388
|
+
<span class="linenos">3</span><span class="c1">// With the classic syntax, this callback expects an integer and returns nothing</span>
|
|
389
|
+
<span class="linenos">4</span><span class="kd">const</span> <span class="nx">ExampleCallback</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">callback</span><span class="p">(</span><span class="s1">'ExampleCallback'</span><span class="p">,</span> <span class="s1">'void'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'int'</span><span class="p">]);</span>
|
|
390
|
+
<span class="linenos">5</span>
|
|
391
|
+
<span class="linenos">6</span><span class="c1">// With the prototype parser, this callback expects a double and float, and returns the sum as a double</span>
|
|
392
|
+
<span class="linenos">7</span><span class="kd">const</span> <span class="nx">AddDoubleFloat</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">callback</span><span class="p">(</span><span class="s1">'double AddDoubleFloat(double d, float f)'</span><span class="p">);</span>
|
|
393
|
+
</pre></div>
|
|
394
|
+
</div>
|
|
395
|
+
<p>Once your callback type is declared, you can use them in struct definitions, or as function parameter and/or return type.</p>
|
|
396
|
+
<p>Here is a small example with the C part and the JS part.</p>
|
|
397
|
+
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><string.h></span><span class="cp"></span>
|
|
398
|
+
<span class="linenos">2</span>
|
|
399
|
+
<span class="linenos">3</span><span class="kt">int</span><span class="w"> </span><span class="nf">TransferToJS</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">name</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">age</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">cb</span><span class="p">)(</span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">str</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">age</span><span class="p">))</span><span class="w"></span>
|
|
400
|
+
<span class="linenos">4</span><span class="p">{</span><span class="w"></span>
|
|
401
|
+
<span class="linenos">5</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">buf</span><span class="p">[</span><span class="mi">64</span><span class="p">];</span><span class="w"></span>
|
|
402
|
+
<span class="linenos">6</span><span class="w"> </span><span class="n">snprintf</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">buf</span><span class="p">),</span><span class="w"> </span><span class="s">"Hello %s!"</span><span class="p">,</span><span class="w"> </span><span class="n">str</span><span class="p">);</span><span class="w"></span>
|
|
403
|
+
<span class="linenos">7</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">cb</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span><span class="w"> </span><span class="n">age</span><span class="p">);</span><span class="w"></span>
|
|
404
|
+
<span class="linenos">8</span><span class="p">}</span><span class="w"></span>
|
|
405
|
+
</pre></div>
|
|
406
|
+
</div>
|
|
407
|
+
<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">'koffi'</span><span class="p">);</span>
|
|
408
|
+
<span class="linenos"> 2</span>
|
|
409
|
+
<span class="linenos"> 3</span><span class="kd">const</span> <span class="nx">TransferCallback</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">callback</span><span class="p">(</span><span class="s1">'int TransferCallback(const char *str, int age)'</span><span class="p">);</span>
|
|
410
|
+
<span class="linenos"> 4</span>
|
|
411
|
+
<span class="linenos"> 5</span><span class="kd">const</span> <span class="nx">TransferToJS</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">'int TransferToJS(const char *str, int age, TransferCallback cb)'</span><span class="p">);</span>
|
|
412
|
+
<span class="linenos"> 6</span>
|
|
413
|
+
<span class="linenos"> 7</span><span class="kd">let</span> <span class="nx">ret</span> <span class="o">=</span> <span class="nx">TransferToJS</span><span class="p">(</span><span class="s1">'Niels'</span><span class="p">,</span> <span class="mf">27</span><span class="p">,</span> <span class="p">(</span><span class="nx">str</span><span class="p">,</span> <span class="nx">age</span><span class="p">)</span> <span class="p">=></span> <span class="p">{</span>
|
|
414
|
+
<span class="linenos"> 8</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>
|
|
415
|
+
<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="s1">'Your age is:'</span><span class="p">,</span> <span class="nx">age</span><span class="p">);</span>
|
|
416
|
+
<span class="linenos">10</span> <span class="k">return</span> <span class="mf">42</span><span class="p">;</span>
|
|
417
|
+
<span class="linenos">11</span><span class="p">});</span>
|
|
418
|
+
<span class="linenos">12</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">ret</span><span class="p">);</span>
|
|
419
|
+
<span class="linenos">13</span>
|
|
420
|
+
<span class="linenos">14</span><span class="c1">// This example prints:</span>
|
|
421
|
+
<span class="linenos">15</span><span class="c1">// Hello Niels!</span>
|
|
422
|
+
<span class="linenos">16</span><span class="c1">// Your age is: 27</span>
|
|
423
|
+
<span class="linenos">17</span><span class="c1">// 42</span>
|
|
424
|
+
</pre></div>
|
|
425
|
+
</div>
|
|
426
|
+
<p>On x86 platforms, only Cdecl and Stdcall callbacks are supported.</p>
|
|
427
|
+
</section>
|
|
428
|
+
<section id="thread-safety">
|
|
429
|
+
<h3>Thread safety<a class="headerlink" href="#thread-safety" title="Permalink to this heading">#</a></h3>
|
|
430
|
+
<p>The callback must be called from the main thread, or more precisely from the same thread as the V8 intepreter.</p>
|
|
431
|
+
<p>Calling the callback from another thread is undefined behavior, and will likely lead to a mess.</p>
|
|
432
|
+
</section>
|
|
433
|
+
</section>
|
|
434
|
+
</section>
|
|
435
|
+
|
|
436
|
+
</article>
|
|
437
|
+
</div>
|
|
438
|
+
<footer>
|
|
439
|
+
|
|
440
|
+
<div class="related-pages">
|
|
441
|
+
<a class="next-page" href="memory">
|
|
442
|
+
<div class="page-info">
|
|
443
|
+
<div class="context">
|
|
444
|
+
<span>Next</span>
|
|
445
|
+
</div>
|
|
446
|
+
<div class="title">Memory usage</div>
|
|
447
|
+
</div>
|
|
448
|
+
<svg><use href="#svg-arrow-right"></use></svg>
|
|
449
|
+
</a>
|
|
450
|
+
<a class="prev-page" href="types">
|
|
451
|
+
<svg><use href="#svg-arrow-right"></use></svg>
|
|
452
|
+
<div class="page-info">
|
|
453
|
+
<div class="context">
|
|
454
|
+
<span>Previous</span>
|
|
455
|
+
</div>
|
|
456
|
+
|
|
457
|
+
<div class="title">Data types</div>
|
|
458
|
+
|
|
459
|
+
</div>
|
|
460
|
+
</a>
|
|
461
|
+
</div>
|
|
462
|
+
<div class="bottom-of-page">
|
|
463
|
+
<div class="left-details">
|
|
464
|
+
<div class="copyright">
|
|
465
|
+
Copyright © 2022, Niels Martignène
|
|
466
|
+
</div>
|
|
467
|
+
Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
|
|
468
|
+
|
|
469
|
+
<a href="https://github.com/pradyunsg/furo">Furo</a>
|
|
470
|
+
|
|
471
|
+
</div>
|
|
472
|
+
<div class="right-details">
|
|
473
|
+
<div class="icons">
|
|
474
|
+
|
|
475
|
+
</div>
|
|
476
|
+
</div>
|
|
477
|
+
</div>
|
|
478
|
+
|
|
479
|
+
</footer>
|
|
480
|
+
</div>
|
|
481
|
+
<aside class="toc-drawer">
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
<div class="toc-sticky toc-scroll">
|
|
485
|
+
<div class="toc-title-container">
|
|
486
|
+
<span class="toc-title">
|
|
487
|
+
Contents
|
|
488
|
+
</span>
|
|
489
|
+
</div>
|
|
490
|
+
<div class="toc-tree-container">
|
|
491
|
+
<div class="toc-tree">
|
|
492
|
+
<ul>
|
|
493
|
+
<li><a class="reference internal" href="#">Function calls</a><ul>
|
|
494
|
+
<li><a class="reference internal" href="#function-definitions">Function definitions</a><ul>
|
|
495
|
+
<li><a class="reference internal" href="#classic-syntax">Classic syntax</a></li>
|
|
496
|
+
<li><a class="reference internal" href="#c-like-prototypes">C-like prototypes</a></li>
|
|
497
|
+
</ul>
|
|
498
|
+
</li>
|
|
499
|
+
<li><a class="reference internal" href="#synchronous-calls">Synchronous calls</a></li>
|
|
500
|
+
<li><a class="reference internal" href="#asynchronous-calls">Asynchronous calls</a></li>
|
|
501
|
+
<li><a class="reference internal" href="#variadic-functions">Variadic functions</a></li>
|
|
502
|
+
<li><a class="reference internal" href="#output-parameters">Output parameters</a><ul>
|
|
503
|
+
<li><a class="reference internal" href="#struct-example">Struct example</a></li>
|
|
504
|
+
<li><a class="reference internal" href="#opaque-handle-example">Opaque handle example</a></li>
|
|
505
|
+
</ul>
|
|
506
|
+
</li>
|
|
507
|
+
<li><a class="reference internal" href="#javascript-callbacks">Javascript callbacks</a><ul>
|
|
508
|
+
<li><a class="reference internal" href="#using-callbacks">Using callbacks</a></li>
|
|
509
|
+
<li><a class="reference internal" href="#thread-safety">Thread safety</a></li>
|
|
510
|
+
</ul>
|
|
511
|
+
</li>
|
|
512
|
+
</ul>
|
|
513
|
+
</li>
|
|
514
|
+
</ul>
|
|
515
|
+
|
|
516
|
+
</div>
|
|
517
|
+
</div>
|
|
518
|
+
</div>
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
</aside>
|
|
522
|
+
</div>
|
|
523
|
+
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
|
524
|
+
<script src="_static/jquery.js"></script>
|
|
525
|
+
<script src="_static/underscore.js"></script>
|
|
526
|
+
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
|
|
527
|
+
<script src="_static/doctools.js"></script>
|
|
528
|
+
<script src="_static/scripts/furo.js"></script>
|
|
529
|
+
</body>
|
|
530
|
+
</html>
|