docker 为什么libxml2_xpath失败,原因是FFI指针类型无效、应为null或External

vc6uscn9  于 2023-10-16  发布在  Docker
关注(0)|答案(1)|浏览(79)

在流水线应用程序中使用Denos libxml2_xpath即使在docker下也会失败
运行

docker run  
\--interactive  \\ 
\--tty   \\ 
\--platform linux/amd64   
\--rm     
\--volume $PWD:/app    
\--volume $HOME/.deno:/deno-dir    
\--workdir /app     
deno deno run --allow-read --allow-ffi --unstable examples/parse-xcb.ts

失败原因

error: Uncaught (in promise) TypeError: Invalid FFI pointer type, expected null, or External
this.#ptr = lib.symbols.xmlCreatePushParserCtxt(
^
at new PushParseCtxt (https://deno.land/x/[email protected]/mod.ts:89:29)
at parseDocument (https://deno.land/x/[email protected]/mod.ts:442:17)
at eventLoopTick (ext:core/01_core.js:183:11)
at async file:///app/examples/parse-xcb.ts:9:15

Macbook M1上的Dockefile

FROM --platform=linux/amd64 denoland/deno:1.37.0

RUN DEBIAN_FRONTEND=noninteractive  \
apt-get update                      \
&& apt-get install -qy              \
libxml2-utils                       \
libxml2-dev                         \
libxml2
nom7f22z

nom7f22z1#

该第三方库已过时https://deno.land/x/libxml2_xpath),它使用的是pointer类型,而它应该是buffer,因为它传递的是Uint8Array

https://docs.deno.com/runtime/manual/runtime/ffi_api#supported-types
从Deno 1.25开始,指针类型已被拆分为指针和 * 缓冲区类型,以确保用户利用类型化数组的优化,而从Deno 1.31开始,指针的JavaScript表示已成为不透明的指针对象或空指针的null。
一旦你从这个库中更改了源代码:

"xmlCreatePushParserCtxt": {
    parameters: ["pointer", "pointer", "pointer", "usize", "pointer"],
    result: "pointer",
    nonblocking: false,
  },

收件人:

"xmlCreatePushParserCtxt": {
    parameters: ["pointer", "pointer", "buffer", "usize", "buffer"],
    result: "pointer",
    nonblocking: false,
  },

你再也不会犯这种错误了。但是,由于库非常过时,会触发其他错误。它使用不稳定的FFI API,这要求项目保持最新。
如果你将构造函数改为:

constructor(chunk: Uint8Array) {
    this.#ptr = lib.symbols.xmlCreatePushParserCtxt(
      null,
      null,
      chunk,
      chunk.length,
      cstr("<mem>"),
    );
    if (typeof this.#ptr !== 'object') {
      throw new Error(`${this.#ptr}`);
    }
  }

调用parseDocument(stream)时,库不再崩溃。但它在使用XPathContext(doc)时崩溃。它不会工作,直到你取代所有过时的FFI类型。
你应该找到一个新的库或完全更新那个库。

相关问题