koffi 1.3.6 → 1.3.7
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/ChangeLog.md +13 -0
- package/benchmark/atoi_koffi.js +1 -1
- package/benchmark/raylib_koffi.js +4 -4
- package/build/qemu/1.3.7/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.7/koffi_win32_x64.tar.gz +0 -0
- package/doc/_static/perf_linux_20220628.png +0 -0
- package/doc/benchmarks.xlsx +0 -0
- package/doc/contribute.md +3 -6
- package/doc/dist/doctrees/changes.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/start.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/dist/html/_sources/contribute.md.txt +3 -6
- package/doc/dist/html/_sources/functions.md.txt +9 -8
- package/doc/dist/html/_sources/start.md.txt +2 -2
- package/doc/dist/html/_sources/types.md.txt +15 -11
- package/doc/dist/html/_static/basic.css +12 -14
- package/doc/dist/html/_static/perf_linux_20220628.png +0 -0
- package/doc/dist/html/benchmarks.html +1 -1
- package/doc/dist/html/changes.html +16 -1
- package/doc/dist/html/contribute.html +4 -7
- package/doc/dist/html/functions.html +18 -17
- package/doc/dist/html/genindex.html +1 -1
- package/doc/dist/html/index.html +4 -3
- package/doc/dist/html/memory.html +1 -1
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +2 -2
- package/doc/dist/html/search.html +1 -1
- package/doc/dist/html/searchindex.js +1 -1
- package/doc/dist/html/start.html +3 -3
- package/doc/dist/html/types.html +30 -10
- package/doc/functions.md +9 -8
- package/doc/start.md +2 -2
- package/doc/types.md +15 -11
- package/package.json +1 -1
- package/qemu/qemu.js +12 -2
- package/src/call.cc +17 -9
- package/src/ffi.cc +14 -5
- package/src/ffi.hh +0 -1
- package/src/util.cc +1 -1
- package/test/async.js +1 -1
- package/test/callbacks.js +25 -2
- package/test/misc.c +52 -2
- package/test/raylib.js +4 -4
- package/test/sqlite.js +5 -5
- package/test/sync.js +22 -7
- package/build/qemu/1.3.6/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.6/koffi_win32_x64.tar.gz +0 -0
package/src/ffi.cc
CHANGED
|
@@ -1075,9 +1075,12 @@ static void RegisterPrimitiveType(InstanceData *instance, const char *name, Prim
|
|
|
1075
1075
|
instance->types_map.Set(type);
|
|
1076
1076
|
}
|
|
1077
1077
|
|
|
1078
|
-
|
|
1078
|
+
template <typename T>
|
|
1079
|
+
static inline PrimitiveKind GetIntegerPrimitive(bool sign)
|
|
1079
1080
|
{
|
|
1080
|
-
switch (RG_SIZE(
|
|
1081
|
+
switch (RG_SIZE(T)) {
|
|
1082
|
+
case 1: return sign ? PrimitiveKind::Int8 : PrimitiveKind::UInt8;
|
|
1083
|
+
case 2: return sign ? PrimitiveKind::Int16 : PrimitiveKind::UInt16;
|
|
1081
1084
|
case 4: return sign ? PrimitiveKind::Int32 : PrimitiveKind::UInt32;
|
|
1082
1085
|
case 8: return sign ? PrimitiveKind::Int64 : PrimitiveKind::UInt64;
|
|
1083
1086
|
}
|
|
@@ -1121,9 +1124,13 @@ static Napi::Object InitBaseTypes(Napi::Env env)
|
|
|
1121
1124
|
RegisterPrimitiveType(instance, "int64_t", PrimitiveKind::Int64, 8, alignof(int64_t));
|
|
1122
1125
|
RegisterPrimitiveType(instance, "uint64", PrimitiveKind::UInt64, 8, alignof(int64_t));
|
|
1123
1126
|
RegisterPrimitiveType(instance, "uint64_t", PrimitiveKind::UInt64, 8, alignof(int64_t));
|
|
1124
|
-
RegisterPrimitiveType(instance, "
|
|
1125
|
-
RegisterPrimitiveType(instance, "
|
|
1126
|
-
RegisterPrimitiveType(instance, "
|
|
1127
|
+
RegisterPrimitiveType(instance, "intptr", GetIntegerPrimitive<intptr_t>(true), RG_SIZE(intptr_t), alignof(intptr_t));
|
|
1128
|
+
RegisterPrimitiveType(instance, "intptr_t", GetIntegerPrimitive<intptr_t>(true), RG_SIZE(intptr_t), alignof(intptr_t));
|
|
1129
|
+
RegisterPrimitiveType(instance, "uintptr", GetIntegerPrimitive<intptr_t>(false), RG_SIZE(intptr_t), alignof(intptr_t));
|
|
1130
|
+
RegisterPrimitiveType(instance, "uintptr_t", GetIntegerPrimitive<intptr_t>(false), RG_SIZE(intptr_t), alignof(intptr_t));
|
|
1131
|
+
RegisterPrimitiveType(instance, "long", GetIntegerPrimitive<long>(true), RG_SIZE(long), alignof(long));
|
|
1132
|
+
RegisterPrimitiveType(instance, "ulong", GetIntegerPrimitive<long>(false), RG_SIZE(long), alignof(long));
|
|
1133
|
+
RegisterPrimitiveType(instance, "unsigned long", GetIntegerPrimitive<long>(false), RG_SIZE(long), alignof(long));
|
|
1127
1134
|
RegisterPrimitiveType(instance, "longlong", PrimitiveKind::Int64, RG_SIZE(int64_t), alignof(int64_t));
|
|
1128
1135
|
RegisterPrimitiveType(instance, "long long", PrimitiveKind::Int64, RG_SIZE(int64_t), alignof(int64_t));
|
|
1129
1136
|
RegisterPrimitiveType(instance, "ulonglong", PrimitiveKind::UInt64, RG_SIZE(uint64_t), alignof(uint64_t));
|
|
@@ -1134,6 +1141,8 @@ static Napi::Object InitBaseTypes(Napi::Env env)
|
|
|
1134
1141
|
RegisterPrimitiveType(instance, "double", PrimitiveKind::Float64, 8, alignof(double));
|
|
1135
1142
|
RegisterPrimitiveType(instance, "string", PrimitiveKind::String, RG_SIZE(void *), alignof(void *));
|
|
1136
1143
|
RegisterPrimitiveType(instance, "string16", PrimitiveKind::String16, RG_SIZE(void *), alignof(void *));
|
|
1144
|
+
RegisterPrimitiveType(instance, "str", PrimitiveKind::String, RG_SIZE(void *), alignof(void *));
|
|
1145
|
+
RegisterPrimitiveType(instance, "str16", PrimitiveKind::String16, RG_SIZE(void *), alignof(void *));
|
|
1137
1146
|
|
|
1138
1147
|
Napi::Object types = Napi::Object::New(env);
|
|
1139
1148
|
for (TypeInfo &type: instance->types) {
|
package/src/ffi.hh
CHANGED
package/src/util.cc
CHANGED
|
@@ -28,7 +28,7 @@ const TypeInfo *ResolveType(const InstanceData *instance, Napi::Value value, int
|
|
|
28
28
|
const TypeInfo *type = instance->types_map.FindValue(str.c_str(), nullptr);
|
|
29
29
|
|
|
30
30
|
if (!type) {
|
|
31
|
-
ThrowError<Napi::TypeError>(value.Env(), "Unknown type
|
|
31
|
+
ThrowError<Napi::TypeError>(value.Env(), "Unknown type name '%1'", str.c_str());
|
|
32
32
|
return nullptr;
|
|
33
33
|
}
|
|
34
34
|
|
package/test/async.js
CHANGED
package/test/callbacks.js
CHANGED
|
@@ -21,7 +21,7 @@ const BFG = koffi.struct('BFG', {
|
|
|
21
21
|
a: 'int8_t',
|
|
22
22
|
b: 'int64_t',
|
|
23
23
|
c: 'char',
|
|
24
|
-
d: '
|
|
24
|
+
d: 'str',
|
|
25
25
|
e: 'short',
|
|
26
26
|
inner: koffi.struct({
|
|
27
27
|
f: 'float',
|
|
@@ -30,9 +30,16 @@ const BFG = koffi.struct('BFG', {
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
const SimpleCallback = koffi.callback('int SimpleCallback(const char *str)');
|
|
33
|
-
const RecursiveCallback = koffi.callback('RecursiveCallback', 'float', ['int', '
|
|
33
|
+
const RecursiveCallback = koffi.callback('RecursiveCallback', 'float', ['int', 'str', 'double']);
|
|
34
34
|
const BigCallback = koffi.callback('BFG BigCallback(BFG bfg)');
|
|
35
35
|
const ApplyCallback = koffi.callback('int __stdcall ApplyCallback(int a, int b, int c)');
|
|
36
|
+
const IntCallback = koffi.callback('int IntCallback(int x)');
|
|
37
|
+
|
|
38
|
+
const StructCallbacks = koffi.struct('StructCallbacks', {
|
|
39
|
+
first: IntCallback,
|
|
40
|
+
second: IntCallback,
|
|
41
|
+
third: IntCallback
|
|
42
|
+
});
|
|
36
43
|
|
|
37
44
|
main();
|
|
38
45
|
|
|
@@ -54,6 +61,8 @@ async function test() {
|
|
|
54
61
|
const CallRecursiveJS = lib.func('float CallRecursiveJS(int i, RecursiveCallback func)');
|
|
55
62
|
const ModifyBFG = lib.func('BFG ModifyBFG(int x, double y, const char *str, BigCallback func, _Out_ BFG *p)');
|
|
56
63
|
const ApplyStd = lib.func('int ApplyStd(int a, int b, int c, ApplyCallback func)');
|
|
64
|
+
const ApplyMany = lib.func('int ApplyMany(int x, IntCallback *funcs, int length)');
|
|
65
|
+
const ApplyStruct = lib.func('int ApplyStruct(int x, StructCallbacks callbacks)');
|
|
57
66
|
|
|
58
67
|
// Simple test similar to README example
|
|
59
68
|
{
|
|
@@ -92,4 +101,18 @@ async function test() {
|
|
|
92
101
|
let ret = ApplyStd(1, 5, 9, (a, b, c) => a + b * c);
|
|
93
102
|
assert.equal(ret, 46);
|
|
94
103
|
}
|
|
104
|
+
|
|
105
|
+
// Array of callbacks
|
|
106
|
+
{
|
|
107
|
+
let callbacks = [x => x * 5, x => x - 42, x => -x];
|
|
108
|
+
let ret = ApplyMany(27, callbacks, callbacks.length);
|
|
109
|
+
assert.equal(ret, -93);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Struct of callbacks
|
|
113
|
+
{
|
|
114
|
+
let callbacks = { first: x => -x, second: x => x * 5, third: x => x - 42 };
|
|
115
|
+
let ret = ApplyStruct(27, callbacks);
|
|
116
|
+
assert.equal(ret, -177);
|
|
117
|
+
}
|
|
95
118
|
}
|
package/test/misc.c
CHANGED
|
@@ -129,6 +129,20 @@ typedef struct IntContainer {
|
|
|
129
129
|
int len;
|
|
130
130
|
} IntContainer;
|
|
131
131
|
|
|
132
|
+
typedef struct StrStruct {
|
|
133
|
+
const char *str;
|
|
134
|
+
const char16_t *str16;
|
|
135
|
+
} StrStruct;
|
|
136
|
+
|
|
137
|
+
typedef int STDCALL ApplyCallback(int a, int b, int c);
|
|
138
|
+
typedef int IntCallback(int x);
|
|
139
|
+
|
|
140
|
+
typedef struct StructCallbacks {
|
|
141
|
+
IntCallback *first;
|
|
142
|
+
IntCallback *second;
|
|
143
|
+
IntCallback *third;
|
|
144
|
+
} StructCallbacks;
|
|
145
|
+
|
|
132
146
|
EXPORT int8_t GetMinusOne1(void)
|
|
133
147
|
{
|
|
134
148
|
return -1;
|
|
@@ -535,8 +549,6 @@ EXPORT BFG ModifyBFG(int x, double y, const char *str, BFG (*func)(BFG bfg), BFG
|
|
|
535
549
|
return bfg;
|
|
536
550
|
}
|
|
537
551
|
|
|
538
|
-
typedef int STDCALL ApplyCallback(int a, int b, int c);
|
|
539
|
-
|
|
540
552
|
EXPORT int ApplyStd(int a, int b, int c, ApplyCallback *func)
|
|
541
553
|
{
|
|
542
554
|
int ret = func(a, b, c);
|
|
@@ -568,3 +580,41 @@ EXPORT void MultiplyIntegers(int multiplier, int *values, int len)
|
|
|
568
580
|
values[i] *= multiplier;
|
|
569
581
|
}
|
|
570
582
|
}
|
|
583
|
+
|
|
584
|
+
EXPORT const char *ThroughStr(StrStruct s)
|
|
585
|
+
{
|
|
586
|
+
return s.str;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
EXPORT const char16_t *ThroughStr16(StrStruct s)
|
|
590
|
+
{
|
|
591
|
+
return s.str16;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
EXPORT const char *ThroughStrStar(StrStruct *s)
|
|
595
|
+
{
|
|
596
|
+
return s->str;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
EXPORT const char16_t *ThroughStrStar16(StrStruct *s)
|
|
600
|
+
{
|
|
601
|
+
return s->str16;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
EXPORT int ApplyMany(int x, IntCallback **callbacks, int length)
|
|
605
|
+
{
|
|
606
|
+
for (int i = 0; i < length; i++) {
|
|
607
|
+
x = (callbacks[i])(x);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
return x;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
EXPORT int ApplyStruct(int x, StructCallbacks callbacks)
|
|
614
|
+
{
|
|
615
|
+
x = callbacks.first(x);
|
|
616
|
+
x = callbacks.second(x);
|
|
617
|
+
x = callbacks.third(x);
|
|
618
|
+
|
|
619
|
+
return x;
|
|
620
|
+
}
|
package/test/raylib.js
CHANGED
|
@@ -86,14 +86,14 @@ async function test() {
|
|
|
86
86
|
let lib_filename = path.dirname(__filename) + '/build/raylib' + koffi.extension;
|
|
87
87
|
let lib = koffi.load(lib_filename);
|
|
88
88
|
|
|
89
|
-
const InitWindow = lib.func('InitWindow', 'void', ['int', 'int', '
|
|
89
|
+
const InitWindow = lib.func('InitWindow', 'void', ['int', 'int', 'str']);
|
|
90
90
|
const SetTraceLogLevel = lib.func('SetTraceLogLevel', 'void', ['int']);
|
|
91
91
|
const SetWindowState = lib.func('SetWindowState', 'void', ['uint']);
|
|
92
92
|
const GenImageColor = lib.func('GenImageColor', Image, ['int', 'int', Color]);
|
|
93
93
|
const GetFontDefault = lib.func('GetFontDefault', Font, []);
|
|
94
|
-
const MeasureTextEx = lib.func('MeasureTextEx', Vector2, [Font, '
|
|
95
|
-
const ImageDrawTextEx = lib.func('ImageDrawTextEx', 'void', [koffi.pointer(Image), Font, '
|
|
96
|
-
const ExportImage = lib.func('ExportImage', 'bool', [Image, '
|
|
94
|
+
const MeasureTextEx = lib.func('MeasureTextEx', Vector2, [Font, 'str', 'float', 'float']);
|
|
95
|
+
const ImageDrawTextEx = lib.func('ImageDrawTextEx', 'void', [koffi.pointer(Image), Font, 'str', Vector2, 'float', 'float', Color]);
|
|
96
|
+
const ExportImage = lib.func('ExportImage', 'bool', [Image, 'str']);
|
|
97
97
|
|
|
98
98
|
// We need to call InitWindow before using anything else (such as fonts)
|
|
99
99
|
SetTraceLogLevel(4); // Warnings
|
package/test/sqlite.js
CHANGED
|
@@ -39,13 +39,13 @@ async function test() {
|
|
|
39
39
|
let lib_filename = path.dirname(__filename) + '/build/sqlite3' + koffi.extension;
|
|
40
40
|
let lib = koffi.load(lib_filename);
|
|
41
41
|
|
|
42
|
-
const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['
|
|
43
|
-
const sqlite3_exec = lib.func('sqlite3_exec', 'int', [sqlite3_db, '
|
|
44
|
-
const sqlite3_prepare_v2 = lib.func('sqlite3_prepare_v2', 'int', [sqlite3_db, '
|
|
42
|
+
const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['str', koffi.out(koffi.pointer(sqlite3_db)), 'int', 'str']);
|
|
43
|
+
const sqlite3_exec = lib.func('sqlite3_exec', 'int', [sqlite3_db, 'str', 'void *', 'void *', 'void *']);
|
|
44
|
+
const sqlite3_prepare_v2 = lib.func('sqlite3_prepare_v2', 'int', [sqlite3_db, 'str', 'int', koffi.out(koffi.pointer(sqlite3_stmt)), 'string']);
|
|
45
45
|
const sqlite3_reset = lib.func('sqlite3_reset', 'int', [sqlite3_stmt]);
|
|
46
|
-
const sqlite3_bind_text = lib.func('sqlite3_bind_text', 'int', [sqlite3_stmt, 'int', '
|
|
46
|
+
const sqlite3_bind_text = lib.func('sqlite3_bind_text', 'int', [sqlite3_stmt, 'int', 'str', 'int', 'void *']);
|
|
47
47
|
const sqlite3_bind_int = lib.func('sqlite3_bind_int', 'int', [sqlite3_stmt, 'int', 'int']);
|
|
48
|
-
const sqlite3_column_text = lib.func('sqlite3_column_text', '
|
|
48
|
+
const sqlite3_column_text = lib.func('sqlite3_column_text', 'str', [sqlite3_stmt, 'int']);
|
|
49
49
|
const sqlite3_column_int = lib.func('sqlite3_column_int', 'int', [sqlite3_stmt, 'int']);
|
|
50
50
|
const sqlite3_step = lib.func('sqlite3_step', 'int', [sqlite3_stmt]);
|
|
51
51
|
const sqlite3_finalize = lib.func('sqlite3_finalize', 'int', [sqlite3_stmt]);
|
package/test/sync.js
CHANGED
|
@@ -64,7 +64,7 @@ const BFG = koffi.struct('BFG', {
|
|
|
64
64
|
a: 'int8_t',
|
|
65
65
|
b: 'int64_t',
|
|
66
66
|
c: 'char',
|
|
67
|
-
d: '
|
|
67
|
+
d: 'str',
|
|
68
68
|
e: 'short',
|
|
69
69
|
inner: koffi.struct({
|
|
70
70
|
f: 'float',
|
|
@@ -75,7 +75,7 @@ const PackedBFG = koffi.pack('PackedBFG', {
|
|
|
75
75
|
a: 'int8_t',
|
|
76
76
|
b: 'int64_t',
|
|
77
77
|
c: 'char',
|
|
78
|
-
d: '
|
|
78
|
+
d: 'str',
|
|
79
79
|
e: 'short',
|
|
80
80
|
inner: koffi.pack({
|
|
81
81
|
f: 'float',
|
|
@@ -106,6 +106,11 @@ const IntContainer = koffi.struct('IntContainer', {
|
|
|
106
106
|
len: 'int'
|
|
107
107
|
});
|
|
108
108
|
|
|
109
|
+
const StrStruct = koffi.struct('StrStruct', {
|
|
110
|
+
str: 'str',
|
|
111
|
+
str16: 'str16'
|
|
112
|
+
});
|
|
113
|
+
|
|
109
114
|
main();
|
|
110
115
|
|
|
111
116
|
async function main() {
|
|
@@ -146,13 +151,13 @@ async function test() {
|
|
|
146
151
|
const ConcatenateToInt1 = lib.func('ConcatenateToInt1', 'int64_t', Array(12).fill('int8_t'));
|
|
147
152
|
const ConcatenateToInt4 = lib.func('ConcatenateToInt4', 'int64_t', Array(12).fill('int32_t'));
|
|
148
153
|
const ConcatenateToInt8 = lib.func('ConcatenateToInt8', 'int64_t', Array(12).fill('int64_t'));
|
|
149
|
-
const ConcatenateToStr1 = lib.func('ConcatenateToStr1', '
|
|
150
|
-
const ConcatenateToStr4 = lib.func('ConcatenateToStr4', '
|
|
151
|
-
const ConcatenateToStr8 = lib.func('ConcatenateToStr8', '
|
|
154
|
+
const ConcatenateToStr1 = lib.func('ConcatenateToStr1', 'str', [...Array(8).fill('int8_t'), koffi.struct('IJK1', {i: 'int8_t', j: 'int8_t', k: 'int8_t'}), 'int8_t']);
|
|
155
|
+
const ConcatenateToStr4 = lib.func('ConcatenateToStr4', 'str', [...Array(8).fill('int32_t'), koffi.pointer(koffi.struct('IJK4', {i: 'int32_t', j: 'int32_t', k: 'int32_t'})), 'int32_t']);
|
|
156
|
+
const ConcatenateToStr8 = lib.func('ConcatenateToStr8', 'str', [...Array(8).fill('int64_t'), koffi.struct('IJK8', {i: 'int64_t', j: 'int64_t', k: 'int64_t'}), 'int64_t']);
|
|
152
157
|
const MakeBFG = lib.func('BFG __stdcall MakeBFG(_Out_ BFG *p, int x, double y, const char *str)');
|
|
153
158
|
const MakePackedBFG = lib.func('PackedBFG __fastcall MakePackedBFG(int x, double y, _Out_ PackedBFG *p, const char *str)');
|
|
154
159
|
const ReturnBigString = process.platform == 'win32' ?
|
|
155
|
-
lib.stdcall(1, '
|
|
160
|
+
lib.stdcall(1, 'str', ['str']) :
|
|
156
161
|
lib.func('const char * __stdcall ReturnBigString(const char *str)');
|
|
157
162
|
const PrintFmt = lib.func('const char *PrintFmt(const char *fmt, ...)');
|
|
158
163
|
const Concat16 = lib.func('const char16_t *Concat16(const char16_t *str1, const char16_t *str2)')
|
|
@@ -175,6 +180,8 @@ async function test() {
|
|
|
175
180
|
const ArrayToStruct = lib.func('IntContainer ArrayToStruct(int *ptr, int len)');
|
|
176
181
|
const FillRange = lib.func('void FillRange(int init, int step, _Out_ int *out, int len)');
|
|
177
182
|
const MultiplyIntegers = lib.func('void MultiplyIntegers(int multiplier, _Inout_ int *values, int len)');
|
|
183
|
+
const ThroughStr = lib.func('str ThroughStr(StrStruct s)');
|
|
184
|
+
const ThroughStr16 = lib.func('str16 ThroughStr16(StrStruct s)');
|
|
178
185
|
|
|
179
186
|
// Simple signed value returns
|
|
180
187
|
assert.equal(GetMinusOne1(), -1);
|
|
@@ -292,7 +299,7 @@ async function test() {
|
|
|
292
299
|
|
|
293
300
|
// Variadic
|
|
294
301
|
{
|
|
295
|
-
let str = PrintFmt('foo %d %g %s', 'int', 200, 'double', 1.5, '
|
|
302
|
+
let str = PrintFmt('foo %d %g %s', 'int', 200, 'double', 1.5, 'str', 'BAR');
|
|
296
303
|
assert.equal(str, 'foo 200 1.5 BAR');
|
|
297
304
|
}
|
|
298
305
|
|
|
@@ -367,4 +374,12 @@ async function test() {
|
|
|
367
374
|
assert.deepEqual(out1, [-2, -9, -16, -23, -30, -37, -44, -51, 58, 65]);
|
|
368
375
|
assert.deepEqual(out2, new Int32Array([3 * 13, 3 * 16, 3 * 19, 3 * 22, 3 * 25, 3 * 28, 3 * 31, 34, 37, 40]));
|
|
369
376
|
}
|
|
377
|
+
|
|
378
|
+
// Test struct strings
|
|
379
|
+
{
|
|
380
|
+
assert.equal(ThroughStr({ str: 'Hello', str16: null }), 'Hello');
|
|
381
|
+
assert.equal(ThroughStr({ str: null, str16: 'Hello' }), null);
|
|
382
|
+
assert.equal(ThroughStr16({ str: null, str16: 'World!' }), 'World!');
|
|
383
|
+
assert.equal(ThroughStr16({ str: 'World!', str16: null }), null);
|
|
384
|
+
}
|
|
370
385
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|