WebAssembly Link Error: import object field 'DYNAMICTOP_PTR' is not a Number
WebAssembly Link Error: import object field 'DYNAMICTOP_PTR' is not a Number
以下 C 文件使用 emscripten 编译为 wasm:
int counter = 100;
int count() {
counter += 1;
return counter;
}
$ emcc counter.c -o counter.wasm -s WASM=1 -s SIDE_MODULE=1
没有问题。然后我让 webpack 加载 wasm 文件(使用 wasm-loader)作为 UInt8Array:
var buffer = new ArrayBuffer(648);
var uint8 = new Uint8Array(buffer);
uint8.set([0,97,115,109,1,0,0,0,0,12,6,100,121,108,105,110,107,144,128,192,2,0,1,150,128,128,128,0,5,96,1,127,0,96,1,127,1,127,96,0,1,127,96,2,127,127,0,96,0,0,2,179,129,128,128,0,10,3,101,110,118,14,68,89,78,65,77,73,67,84,79,80,95,80,84,82,3,127,0,3,101,110,118,13,116,101,109,112,68,111,117,98,108,101,80,116,114,3,127,0,3,101,110,118,5,65,66,79,82,84,3,127,0,3,101,110,118,10,109,101,109,111,114,121,66,97,115,101,3,127,0,3,101,110,118,9,116,97,98,108,101,66,97,115,101,3,127,0,6,103,108,111,98,97,108,3,78,97,78,3,124,0,6,103,108,111,98,97,108,8,73,110,102,105,110,105,116,121,3,124,0,3,101,110,118,18,97,98,111,114,116,83,116,97,99,107,79,118,101,114,102,108,111,119,0,0,3,101,110,118,6,109,101,109,111,114,121,2,0,128,2,3,101,110,118,5,116,97,98,108,101,1,112,0,0,3,137,128,128,128,0,8,1,2,0,3,3,2,4,4,6,242,128,128,128,0,20,127,1,35,0,11,127,1,35,1,11,127,1,35,2,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,124,1,35,5,11,124,1,35,6,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,124,1,68,0,0,0,0,0,0,0,0,11,127,1,65,0,11,125,1,67,0,0,0,0,11,125,1,67,0,0,0,0,11,127,0,65,0,11,7,184,128,128,128,0,4,6,95,99,111,117,110,116,0,6,18,95,95,112,111,115,116,95,105,110,115,116,97,110,116,105,97,116,101,0,8,11,114,117,110,80,111,115,116,83,101,116,115,0,7,8,95,99,111,117,110,116,101,114,3,26,9,129,128,128,128,0,0,10,190,129,128,128,0,8,173,128,128,128,0,1,1,127,2,64,35,10,33,1,35,10,32,0,106,36,10,35,10,65,15,106,65,112,113,36,10,35,10,35,11,78,4,64,32,0,16,0,11,32,1,15,0,11,0,11,133,128,128,128,0,0,35,10,15,11,134,128,128,128,0,0,32,0,36,10,11,141,128,128,128,0,0,2,64,32,0,36,10,32,1,36,11,11,11,146,128,128,128,0,0,35,12,65,0,70,4,64,32,0,36,12,32,1,36,13,11,11,161,128,128,128,0,1,4,127,2,64,35,10,33,3,35,3,65,0,106,40,2,0,33,0,32,0,65,1,106,33,1,32,1,15,0,11,0,11,133,128,128,128,0,1,1,127,1,11,152,128,128,128,0,0,2,64,35,3,65,16,106,36,10,35,10,65,128,128,192,2,106,36,11,16,7,11,11,11,135,128,128,128,0,1,0,35,3,11,1,100,]);
然后我的JS代码调用如下:
import Counter from './wasm/counter'
const counter = new Counter();
实例化失败并出现以下错误:
LinkError: import object field 'DYNAMICTOP_PTR' is not a Number
wasm-loader 使用以下默认选项 (importObject) WebAssembly.Instance(module, importObject)
:
{
'global': {},
'env': {
'memory': new Memory({initial: 10, limit: 100}),
'table': new Table({initial: 0, element: 'anyfunc'})
}
}
我做错了什么吗?如何才能成功加载 wasm 代码?
编辑:
按照@Ghillie 的建议,我尝试使用不同的优化标志编译 C 代码:
-O1
、-02
、-O3
、-Os
和 -Oz
抛出 LinkError: import object field 'memoryBase' is not a Number
这是一个不同的错误,但不会解决问题。
编辑 2:
单独添加 -O1
优化标志不起作用,但允许调试代码的不同错误消息因此@Ghillie 和我的回答都为我的问题提供了完整的解决方案。
使用默认 -O0
以外的任何优化标志进行编译。例如:
emcc counter.c -O1 -o counter.wasm -s WASM=1 -s SIDE_MODULE=1
这里列出了各种优化标志:
https://kripken.github.io/emscripten-site/docs/optimizing/Optimizing-Code.html
解决方案似乎是调整 WebAssembly.Instance(module, importObject)
中使用的 importObject
:
{
'env': {
'memoryBase': 0,
'tableBase': 0,
'memory': new WebAssembly.Memory({initial: 256}),
'table': new WebAssembly.Table({initial: 0, element: 'anyfunc'})
}
}
需要 memoryBase
和 tableBase
并且初始内存值太低(抛出 LinkedError: Memory of incompatible size
)。
此外,实例化完成后,我还必须调用 counter.exports._count()
而不是 counter.exports.count()
。
还要感谢@Ghillie,因为确实需要 -O1
优化标志。
编辑:如果您正在阅读这篇文章并且刚刚开始使用 WebAssembly,我对我的第一次经验进行了总结,希望对您有所帮助:WebAssembly 101: a developer's first steps.
以下 C 文件使用 emscripten 编译为 wasm:
int counter = 100;
int count() {
counter += 1;
return counter;
}
$ emcc counter.c -o counter.wasm -s WASM=1 -s SIDE_MODULE=1
没有问题。然后我让 webpack 加载 wasm 文件(使用 wasm-loader)作为 UInt8Array:
var buffer = new ArrayBuffer(648);
var uint8 = new Uint8Array(buffer);
uint8.set([0,97,115,109,1,0,0,0,0,12,6,100,121,108,105,110,107,144,128,192,2,0,1,150,128,128,128,0,5,96,1,127,0,96,1,127,1,127,96,0,1,127,96,2,127,127,0,96,0,0,2,179,129,128,128,0,10,3,101,110,118,14,68,89,78,65,77,73,67,84,79,80,95,80,84,82,3,127,0,3,101,110,118,13,116,101,109,112,68,111,117,98,108,101,80,116,114,3,127,0,3,101,110,118,5,65,66,79,82,84,3,127,0,3,101,110,118,10,109,101,109,111,114,121,66,97,115,101,3,127,0,3,101,110,118,9,116,97,98,108,101,66,97,115,101,3,127,0,6,103,108,111,98,97,108,3,78,97,78,3,124,0,6,103,108,111,98,97,108,8,73,110,102,105,110,105,116,121,3,124,0,3,101,110,118,18,97,98,111,114,116,83,116,97,99,107,79,118,101,114,102,108,111,119,0,0,3,101,110,118,6,109,101,109,111,114,121,2,0,128,2,3,101,110,118,5,116,97,98,108,101,1,112,0,0,3,137,128,128,128,0,8,1,2,0,3,3,2,4,4,6,242,128,128,128,0,20,127,1,35,0,11,127,1,35,1,11,127,1,35,2,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,124,1,35,5,11,124,1,35,6,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,124,1,68,0,0,0,0,0,0,0,0,11,127,1,65,0,11,125,1,67,0,0,0,0,11,125,1,67,0,0,0,0,11,127,0,65,0,11,7,184,128,128,128,0,4,6,95,99,111,117,110,116,0,6,18,95,95,112,111,115,116,95,105,110,115,116,97,110,116,105,97,116,101,0,8,11,114,117,110,80,111,115,116,83,101,116,115,0,7,8,95,99,111,117,110,116,101,114,3,26,9,129,128,128,128,0,0,10,190,129,128,128,0,8,173,128,128,128,0,1,1,127,2,64,35,10,33,1,35,10,32,0,106,36,10,35,10,65,15,106,65,112,113,36,10,35,10,35,11,78,4,64,32,0,16,0,11,32,1,15,0,11,0,11,133,128,128,128,0,0,35,10,15,11,134,128,128,128,0,0,32,0,36,10,11,141,128,128,128,0,0,2,64,32,0,36,10,32,1,36,11,11,11,146,128,128,128,0,0,35,12,65,0,70,4,64,32,0,36,12,32,1,36,13,11,11,161,128,128,128,0,1,4,127,2,64,35,10,33,3,35,3,65,0,106,40,2,0,33,0,32,0,65,1,106,33,1,32,1,15,0,11,0,11,133,128,128,128,0,1,1,127,1,11,152,128,128,128,0,0,2,64,35,3,65,16,106,36,10,35,10,65,128,128,192,2,106,36,11,16,7,11,11,11,135,128,128,128,0,1,0,35,3,11,1,100,]);
然后我的JS代码调用如下:
import Counter from './wasm/counter'
const counter = new Counter();
实例化失败并出现以下错误:
LinkError: import object field 'DYNAMICTOP_PTR' is not a Number
wasm-loader 使用以下默认选项 (importObject) WebAssembly.Instance(module, importObject)
:
{
'global': {},
'env': {
'memory': new Memory({initial: 10, limit: 100}),
'table': new Table({initial: 0, element: 'anyfunc'})
}
}
我做错了什么吗?如何才能成功加载 wasm 代码?
编辑: 按照@Ghillie 的建议,我尝试使用不同的优化标志编译 C 代码:
-O1
、-02
、-O3
、-Os
和 -Oz
抛出 LinkError: import object field 'memoryBase' is not a Number
这是一个不同的错误,但不会解决问题。
编辑 2:
单独添加 -O1
优化标志不起作用,但允许调试代码的不同错误消息因此@Ghillie 和我的回答都为我的问题提供了完整的解决方案。
使用默认 -O0
以外的任何优化标志进行编译。例如:
emcc counter.c -O1 -o counter.wasm -s WASM=1 -s SIDE_MODULE=1
这里列出了各种优化标志:
https://kripken.github.io/emscripten-site/docs/optimizing/Optimizing-Code.html
解决方案似乎是调整 WebAssembly.Instance(module, importObject)
中使用的 importObject
:
{
'env': {
'memoryBase': 0,
'tableBase': 0,
'memory': new WebAssembly.Memory({initial: 256}),
'table': new WebAssembly.Table({initial: 0, element: 'anyfunc'})
}
}
需要 memoryBase
和 tableBase
并且初始内存值太低(抛出 LinkedError: Memory of incompatible size
)。
此外,实例化完成后,我还必须调用 counter.exports._count()
而不是 counter.exports.count()
。
还要感谢@Ghillie,因为确实需要 -O1
优化标志。
编辑:如果您正在阅读这篇文章并且刚刚开始使用 WebAssembly,我对我的第一次经验进行了总结,希望对您有所帮助:WebAssembly 101: a developer's first steps.