zhangyuang / node-ffi-rs

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

在 Mac 平台下调用,pointer参数问题 #59

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"
  }
}

ffi-rs-darwin-arm64

Current Node.js arch

arm64 darwin

Descibe your problem in detail

const result = load({
    library: 'ApplicationServices',
    funcName: 'AXUIElementCopyAttributeValue',
    retType: DataType.I32,
    paramsType: [DataType.External, DataType.String, DataType.External],
    paramsValue: [systemWideElement, 'AXFocusedUIElement', /** 不会传这个参数 */ ],
  });

上面的调用里的第三个参数,不知道怎么传。

func AXUIElementCopyAttributeValue(
    _ element: AXUIElement,
    _ attribute: CFString,
    _ value: UnsafeMutablePointer<CFTypeRef?>
) -> AXError

该函数在 swift 里的定义

const ele = {
    AXRole: '',
    AXTitle: '',
  }

  const Ele = {
    AXRole: DataType.String,
    AXTitle: DataType.String,
  }

  const elePointer = createPointer({
    paramsType: [Ele],
    paramsValue: [ele],
  });

我自己尝试 这样声明 然后 wrapPointer(elePointer)当作第三个参数。 但是调用不成功

What's your expect result

期望拿到元素信息

The reproduction repo address

zhangyuang commented 4 months ago
参数类型对应的 C 语言类型
AXUIElementRef element:

类型: AXUIElementRef
对应的 C 语言类型: AXUIElementRef 是一个指向 __AXUIElement 结构体的指针,实际上是一个 Core Foundation 类型,用于表示一个 UI 元素。
CFStringRef attribute:

类型: CFStringRef
对应的 C 语言类型: CFStringRef 是一个指向 __CFString 结构体的指针,实际上是一个 Core Foundation 类型,用于表示一个不可变的字符串。
CFTypeRef *value:

类型: CFTypeRef *
对应的 C 语言类型: CFTypeRef 是一个指向 __CFType 结构体的指针,实际上是一个 Core Foundation 类型,用于表示任意类型的 Core Foundation 对象。CFTypeRef * 是一个指向 CFTypeRef 的指针,用于接收函数返回的属性值。

业务逻辑的问题可以自行排查

barbara012 commented 4 months ago
参数类型对应的 C 语言类型
AXUIElementRef element:

类型: AXUIElementRef
对应的 C 语言类型: AXUIElementRef 是一个指向 __AXUIElement 结构体的指针,实际上是一个 Core Foundation 类型,用于表示一个 UI 元素。
CFStringRef attribute:

类型: CFStringRef
对应的 C 语言类型: CFStringRef 是一个指向 __CFString 结构体的指针,实际上是一个 Core Foundation 类型,用于表示一个不可变的字符串。
CFTypeRef *value:

类型: CFTypeRef *
对应的 C 语言类型: CFTypeRef 是一个指向 __CFType 结构体的指针,实际上是一个 Core Foundation 类型,用于表示任意类型的 Core Foundation 对象。CFTypeRef * 是一个指向 CFTypeRef 的指针,用于接收函数返回的属性值。

业务逻辑的问题可以自行排查

没理解到,所以第三个参数应该怎么传,大佬可以进一步指导一下不? 第一个参数是通过另一个函数拿到的

const systemWideElement = load({
        library: 'ApplicationServices',
        funcName: 'AXUIElementCreateSystemWide',
        retType: DataType.External,
        paramsType: [],
        paramsValue: []
      });

第二个参数是个常量。 第三个不会了,尝试用 unwrapPointer处理一下 createPointer,还是提示expect External, got: Object,声明如下

const ele = {
      Label: '',
      Title: '',
      Value: '',
      Type: '',
      Position: {
        x: 0,
        y: 0,
      },
      Size: {
        w: 0,
        h: 0,
      }
    }

    const Ele = {
      Label: DataType.String,
      Title: DataType.String,
      Value: DataType.String,
      Type: DataType.String,
      Position: {
        x: DataType.Double,
        y: DataType.Double,
      },
      Size: {
        w: DataType.Double,
        h: DataType.Double,
      }
    }
const elePointer = createPointer({
        paramsType: [Ele],
        paramsValue: [ele],
      });