zhangyuang / node-ffi-rs

Implement ffi in Node.js by Rust and NAPI
MIT License
189 stars 7 forks source link

在 Electron 环境下 对一个 External 执行 restorePointer,程序直接闪退了 #58

Closed barbara012 closed 4 months ago

barbara012 commented 4 months ago

Current ffi-rs version

{
  "name": "ffi-rs",
  "version": "1.0.83",
  "main": "index.js",
  "types": "index.d.ts",
  "description": "A module written in Rust and N-API provides interface (FFI) features for Node.js",
  "napi": {
    "name": "ffi-rs",
    "triples": {
      "additional": [
        "aarch64-apple-darwin",
        "aarch64-unknown-linux-gnu",
        "aarch64-unknown-linux-musl",
        "i686-pc-windows-msvc",
        "x86_64-unknown-linux-musl",
        "aarch64-pc-windows-msvc"
      ]
    }
  },
  "author": "zhangyuang",
  "homepage": "https://github.com/zhangyuang/node-ffi-rs#readme",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/zhangyuang/node-ffi-rs.git"
  },
  "keywords": [
    "ffi",
    "rust",
    "node.js",
    "napi"
  ],
  "files": [
    "index.js",
    "index.d.ts",
    "README.md"
  ],
  "license": "MIT",
  "dependencies": {},
  "devDependencies": {
    "@napi-rs/cli": "^2.15.2",
    "@types/node": "^20.8.7",
    "benny": "^3.7.1",
    "conventional-changelog-cli": "^4.1.0",
    "esno": "^4.0.0",
    "ffi-napi": "^4.0.3",
    "koa": "^2.14.2",
    "shelljs": "^0.8.5",
    "typescript": "^5.4.5"
  },
  "scripts": {
    "artifacts": "napi artifacts",
    "build:c": "node scripts/compile.js",
    "build:dev": "env=development node scripts/build.js",
    "build": "node scripts/build.js",
    "publish:npm": "node scripts/publish.js",
    "test": "esno ./test.ts",
    "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add . && git commit -m \"docs: update changelog.md\" && git push origin master",
    "pub": "npm version patch && git push origin master --tags && npm run changelog",
    "pub:alpha": "npm version prerelease --preid=alpha && git push origin master --tags"
  },
  "optionalDependencies": {
    "@yuuang/ffi-rs-darwin-arm64": "1.0.83",
    "@yuuang/ffi-rs-darwin-x64": "1.0.83",
    "@yuuang/ffi-rs-linux-arm64-gnu": "1.0.83",
    "@yuuang/ffi-rs-linux-arm64-musl": "1.0.83",
    "@yuuang/ffi-rs-linux-x64-gnu": "1.0.83",
    "@yuuang/ffi-rs-linux-x64-musl": "1.0.83",
    "@yuuang/ffi-rs-win32-arm64-msvc": "1.0.83",
    "@yuuang/ffi-rs-win32-ia32-msvc": "1.0.83",
    "@yuuang/ffi-rs-win32-x64-msvc": "1.0.83"
  }
} 

Current Node.js arch

x64 win32

Descibe your problem in detail

const point  = {
  x: 0,
  y: 0,
};
const Point = {
  x: DataType.I32,
  y: DataType.I32,
  ffiTypeTag: DataType.StackStruct,
}l
const pointer = wrapPointer(createPointer({
  paramsType: [Point],
  paramsValue: [point],
}));
const isCatch = load({
    library: "user32",
    funcName: "GetCaretPos",
    retType: DataType.Boolean,
    paramsValue: pointer,
    paramsType: [DataType.External]
  });
const p = restorePointer({
    paramsValue: pointer,
    retType: [Point],
  })

这行 restorePointer 会导致程序闪退(提示: [12828:0704/002445.028:ERROR:crashpad_client_win.cc(868)] not connected)

What's your expect result

期望得到 caret 的坐标,如果有的话

The reproduction repo address

zhangyuang commented 4 months ago

不需要加wrapPointer

barbara012 commented 4 months ago

不需要加wrapPointer

const pointer = createPointer({
  paramsType: [Point],
  paramsValue: [point],
});

这样吗? 还是闪退

zhangyuang commented 4 months ago

不需要加 ffiTypeTag: DataType.StackStruct,

barbara012 commented 4 months ago

不需要加 ffiTypeTag: DataType.StackStruct,

const point  = {
  x: 0,
  y: 0,
}
const Point = {
  x: DataType.I32,
  y: DataType.I32,
}
const pointer = createPointer({
  paramsType: [Point],
  paramsValue: [point],
});
const pos = load({
      library: "user32",
      funcName: "GetCaretPos",
      retType: DataType.Boolean,
      paramsValue: pointer,
      paramsType: [DataType.External]
    });

还是同样的问题

zhangyuang commented 4 months ago

const Point = { x: DataType.I64, y: DataType.I64, } const pos = load({ library: "user32", funcName: "GetCaretPos", retType: DataType.Boolean, paramsValue: wrapPointer(pointer), paramsType: [DataType.External] });

zhangyuang commented 4 months ago

给出完整代码

barbara012 commented 4 months ago

给出完整代码

let timer;
const point = {
  x: 0,
  y: 0,
}
const Point = {
  x: DataType.I64,
  y: DataType.I64,
}
const pointer = createPointer({
  paramsType: [Point],
  paramsValue: [point],
});

const getForegroundWindow = async () => {
  const hwnd = load(
    {
      library: 'user32',
      funcName: 'GetForegroundWindow',
      retType: DataType.I32,
      paramsType: [],
      paramsValue: []
    }
  )
  return hwnd
}

const getCaretPos = async () => {
  const pos = load({
    library: "user32",
    funcName: "GetCaretPos",
    retType: DataType.Boolean,
    paramsValue: wrapPointer(pointer),
    paramsType: [DataType.External]
  });
  return pos;
}
const loop = () => {
  open({
    library: 'user32', // key
    path: 'user32.dll' // path
  })
  if (timer) {
    clearInterval(timer);
  }
  timer = setInterval(async () => {
    const hwnd = await this.getForegroundWindow();
    console.log('hwnd', hwnd);
    if (hwnd) {
      const isCatch = await this.getCaretPos();
      const p = restorePointer({
        paramsValue: pointer,
        retType: [Point],
      })
      console.log(isCatch, point, p);
      // console.log(p)
    }
  }, 2000);
}

loop()

这里

barbara012 commented 4 months ago

给出完整代码

let timer;
const point = {
  x: 0,
  y: 0,
}
const Point = {
  x: DataType.I64,
  y: DataType.I64,
}
const pointer = createPointer({
  paramsType: [Point],
  paramsValue: [point],
});

const getForegroundWindow = async () => {
  const hwnd = load(
    {
      library: 'user32',
      funcName: 'GetForegroundWindow',
      retType: DataType.I32,
      paramsType: [],
      paramsValue: []
    }
  )
  return hwnd
}

const getCaretPos = async () => {
  const pos = load({
    library: "user32",
    funcName: "GetCaretPos",
    retType: DataType.Boolean,
    paramsValue: wrapPointer(pointer),
    paramsType: [DataType.External]
  });
  return pos;
}
const loop = () => {
  open({
    library: 'user32', // key
    path: 'user32.dll' // path
  })
  if (timer) {
    clearInterval(timer);
  }
  timer = setInterval(async () => {
    const hwnd = await this.getForegroundWindow();
    console.log('hwnd', hwnd);
    if (hwnd) {
      const isCatch = await this.getCaretPos();
      const p = restorePointer({
        paramsValue: pointer,
        retType: [Point],
      })
      console.log(isCatch, point, p);
      // console.log(p)
    }
  }, 2000);
}

loop()

这里

结果输出的坐标和原始值一样{x: 0, y: 0}

zhangyuang commented 4 months ago

看起来没什么问题,你应该根据GetCaretPos的返回值以及调用load方法时设置errno:true来自行debug

barbara012 commented 4 months ago

看起来没什么问题,你应该根据GetCaretPos的返回值以及调用load方法时设置errno:true来自行debu

barbara012 commented 4 months ago

看起来没什么问题,你应该根据GetCaretPos的返回值以及调用load方法时设置errno:true来自行debu 加上了,GetCaretPos 的返回值是 true,也没有报错。就是 pointer 的值没发生变化

zhangyuang commented 4 months ago

getcarepos的返回值是int而不是boolean,你应该去查询这个函数的文档来根据errno信息debug

barbara012 commented 4 months ago

谢谢,我会了

zhangyuang commented 4 months ago

问题定位了吗