CGALWASM编译库,内存访问范围 我目前正在尝试制作一个运行WASM编译CGAL程序的库。这 main.cpp看起来像这样: #ifdef emscripten // #define cgal_always_round_to_nearest #define cgal_no_asserti ...

问题描述 投票:0回答:1
ts中的Wapper看起来像这样:

//@ts-ignore import Module from '../core/build/main.js'; interface WasmModule { HEAPU8: Uint8Array; HEAPU32: Uint32Array; HEAPF32: Float32Array; _malloc(size: number): number; _free(ptr: number): void; _create_weighted_straight_skeleton(ptr: number, weightsPtr: number): number; } /** * Each skeleton vertex is represented by x, y and time. Time can be used to calculate z coordinate. */ export type Vertex = [number, number, number]; /** * Each polygon is represented by an array of vertex indices. */ export type Polygon = number[]; /** * Straight skeleton calculation result. */ export interface Skeleton { vertices: Vertex[]; polygons: Polygon[]; } export class SkeletonBuilder { private static module: WasmModule = null; /** * Initializes the WebAssembly module. Must be called before any other method. */ public static async init(): Promise<void> { return Module().then((library: WasmModule) => { this.module = library; }); } /** * Builds a skeleton from a GeoJSON polygon. * The polygon must have at least one ring. The first ring is always the outer ring, and the rest are inner rings. * Outer rings must be counter-clockwise oriented and inner rings must be clockwise oriented. * All rings must be weakly simple. * Each ring must have a duplicate of the first vertex at the end. * @param polygon The GeoJSON polygon. * @param weights The weights for each vertex. */ public static buildFromGeoJSONPolygon(polygon: GeoJSON.Polygon, weights: number[][]): Skeleton { this.checkModule(); return this.buildFromPolygon(polygon.coordinates, weights); } /** * Builds a skeleton from a polygon represented as an array of rings. * The polygon must have at least one ring. The first ring is always the outer ring, and the rest are inner rings. * Outer rings must be counter-clockwise oriented and inner rings must be clockwise oriented. * All rings must be weakly simple. * Each ring must have a duplicate of the first vertex at the end. * @param coordinates The polygon represented as an array of rings. * @param weights The weights for each vertex. */ public static buildFromPolygon(coordinates: number[][][], weights: number[][]): Skeleton { this.checkModule(); const inputBuffer = this.serializeInput(coordinates); const inputPtr = this.module._malloc(inputBuffer.byteLength); this.module.HEAPU8.set(new Uint8Array(inputBuffer), inputPtr); const weightsBuffer = this.serializeWeights(weights); console.log("DEBUG WEIGHTSBUFFER", new Float32Array(weightsBuffer)) const weightsPtr = this.module._malloc(weightsBuffer.byteLength); this.module.HEAPU8.set(new Uint8Array(weightsBuffer), weightsPtr); const ptr = this.module._create_weighted_straight_skeleton(inputPtr, weightsPtr); if (ptr === 0) { return null; } let offset = ptr / 4; const arrayU32 = this.module.HEAPU32; const arrayF32 = this.module.HEAPF32; const vertices: Vertex[] = []; const polygons: number[][] = []; const vertexCount = arrayU32[offset++]; for (let i = 0; i < vertexCount; i++) { const x = arrayF32[offset++]; const y = arrayF32[offset++]; const time = arrayF32[offset++]; vertices.push([x, y, time]); } let polygonVertexCount = arrayU32[offset++]; while (polygonVertexCount > 0) { const polygon = []; for (let i = 0; i < polygonVertexCount; i++) { polygon.push(arrayU32[offset++]); } polygons.push(polygon); polygonVertexCount = arrayU32[offset++]; } // this.module._free(ptr); // this.module._free(inputPtr); // this.module._free(weightsPtr); return { vertices, polygons }; } private static checkModule(): void { if (this.module === null) { throw new Error('The WebAssembly module has not been initialized, call SkeletonBuilder.init() first.'); } } private static serializeInput(input: number[][][]): ArrayBuffer { let size: number = 1; for (const ring of input) { size += 1 + (ring.length - 1) * 2; } const uint32Array = new Uint32Array(size); const float32Array = new Float32Array(uint32Array.buffer); let offset = 0; for (const ring of input) { uint32Array[offset++] = ring.length - 1; for (let i = 0; i < ring.length - 1; i++) { float32Array[offset++] = ring[i][0]; float32Array[offset++] = ring[i][1]; } } uint32Array[offset++] = 0; return float32Array.buffer; } private static serializeWeights(weights: number[][]): ArrayBuffer { let size: number = 0; for (const ringWeights of weights) { size += ringWeights.length; } const float32Array = new Float32Array(size); let offset = 0; for (const ringWeights of weights) { for (const weight of ringWeights) { float32Array[offset++] = weight; } } return float32Array.buffer; } }

问题似乎是序列压力的函数。不知何故,我弄乱了类型或指针,或者我没有看到的任何东西。
我正在使用权重,我会从WASM中获得“内存访问”错误。如果我不使用转移到CPP的权重,而是在CPP的最后一行中使用一个空{}(generate_weighted_skeleton(data,testWeights);然后代码运行并且不返回问题。
我的猜测是我在这里设置了错误的缓冲区:

const weightsBuffer = this.serializeWeights(weights); console.log("DEBUG WEIGHTSBUFFER", new Float32Array(weightsBuffer)) const weightsPtr = this.module._malloc(weightsBuffer.byteLength); this.module.HEAPU8.set(new Uint8Array(weightsBuffer), weightsPtr);
但是我无法弄清楚这里的问题。

由于我不知道如何在CPP文件为WASM汇编后如何从CPP文件中记录某些内容,所以我很难弄清楚问题是什么。

如果有人知道我如何继续找到问题,我会很高兴!

答案与WASM无关,而更多的是数据类型。 在打字稿方面,我必须更改制作缓冲区的方式:

Https://github.com/pcace/weighted-straight-skeleton/blob/d84eddc9a250914333ccccf1728ab71c30555552a9be/src/src/src/src/wrapper/wrapper/index.ts#l92-l92-l92-l92-l92-l92-l92-l92-l92-l92-l92-l92l1 l92-l107

在CPP一侧,它也需要适应类型:

Https://github.com/pcace/weighted-straight-skeleton/blob/d84eddc9a250914333ccccf1728ab71c30555552a9be/src/src/src/core/core/main.cpp#l183-l192,
c++ typescript webassembly cgal
1个回答
0
投票

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.