云计算百科
云计算领域专业知识百科平台

libOpnedrive-CMake对ModuleOpenDrive配置参数

set_target_properties(ModuleOpenDrive PROPERTIES LINK_FLAGS "\\
–bind \\
-s ENVIRONMENT=web \\
-s MODULARIZE=1 \\
-s EXPORT_NAME='\\"libOpenDrive\\"' \\
-s EXPORTED_RUNTIME_METHODS='[\\"cwrap\\"]' \\
-s FORCE_FILESYSTEM=1 \\
-s ALLOW_MEMORY_GROWTH=1 \\
"
)

明白了!我们将通过一个完整的示例,来演示每个 Emscripten 参数的作用,并且分别展示加上和去掉这些参数后的影响。


示例项目结构

wasm-demo/
├── src/
│ └── main.cpp
├── CMakeLists.txt
└── index.html

1. src/main.cpp(C++ 源码)

#include <emscripten/bind.h>
#include <iostream>
#include <string>

using namespace emscripten;

// 示例类:用于 Embind 测试
class Greeter {
public:
Greeter(const std::string& name) : name(name) {}
std::string greet() const { return "Hello, " + name; }
private:
std::string name;
};

// 示例函数:用于 cwrap 测试
extern "C" {
int add(int a, int b) {
return a + b;
}

const char* sayHello(const char* name) {
static std::string result;
result = "Hello from C++: " + std::string(name);
return result.c_str();
}
}

// 使用 Embind 导出类和方法
EMSCRIPTEN_BINDINGS(my_module) {
class_<Greeter>("Greeter")
.constructor<std::string>()
.function("greet", &Greeter::greet);
}

2. CMakeLists.txt

cmake_minimum_required(VERSION 3.13.4)
project(ModuleOpenDrive)

add_executable(ModuleOpenDrive
src/main.cpp
)

# 设置编译器为 Emscripten
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_C_COMPILER_WORKS TRUE)

# 默认配置,不加任何额外参数
# set_target_properties(ModuleOpenDrive PROPERTIES LINK_FLAGS "\\
# –bind \\
# -s ENVIRONMENT=web \\
# -s MODULARIZE=1 \\
# -s EXPORT_NAME='\\"libOpenDrive\\"' \\
# -s EXPORTED_RUNTIME_METHODS='[\\"cwrap\\"]' \\
# -s FORCE_FILESYSTEM=1 \\
# -s ALLOW_MEMORY_GROWTH=1 \\
# ")

set_target_properties(ModuleOpenDrive PROPERTIES SUFFIX ".js")

3. index.html(JS 调用示例)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Emscripten Demo</title>
</head>
<body>
<h1>WebAssembly Demo</h1>
<script src="ModuleOpenDrive.js"></script>
<script>
// 注意:这里假设没有使用 MODULARIZE 和 EXPORT_NAME 参数
Module.onRuntimeInitialized = function() {
console.log('Module loaded');

// 使用 Embind 类
let greeter = new Module.Greeter("World");
console.log(greeter.greet()); // 输出: Hello, World

// 使用 cwrap 封装函数
const sayHello = Module.cwrap('sayHello', 'string', ['string']);
console.log(sayHello("Alice")); // 输出: Hello from C++: Alice

// 直接调用 _ 函数
console.log(Module._add(2, 3)); // 输出: 5
};
</script>
</body>
</html>


逐个参数说明与 demo

1. –bind

含义:

启用 Embind 功能,允许将 C++ 类导出给 JavaScript。

加上之后:
  • 在 C++ 中使用 EMSCRIPTEN_BINDINGS 定义要导出的类。
  • 在 JS 中可以通过 new Module.Greeter() 创建对象。
去掉之后:
  • Module.Greeter 不会被定义,导致在 JS 中无法创建对象。
  • 错误提示:Module.Greeter is undefined.

C++ 示例:

EMSCRIPTEN_BINDINGS(my_module) {
class_<Greeter>("Greeter")
.constructor<std::string>()
.function("greet", &Greeter::greet);
}

JS 示例:

let greeter = new Module.Greeter("World");
console.log(greeter.greet());

2. -s ENVIRONMENT=web

含义:

指定模块运行环境为浏览器。

加上之后:
  • 确保生成的 .js 文件适用于浏览器环境。
  • 避免 Node.js 特定行为影响浏览器兼容性。
去掉之后:
  • 可能会导致在浏览器中加载时出现问题,特别是如果依赖于特定的浏览器特性或行为。

JS 示例: 无需修改代码,仅确保在 HTML 文件中正确引用 .js 文件即可。

3. -s MODULARIZE=1

含义:

将模块封装为可调用工厂函数,返回 Promise。

加上之后:
  • 模块需要通过 libOpenDrive().then(…) 来加载。
  • 更适合现代 JS 应用开发。
去掉之后:
  • 模块直接作为全局变量 Module 存在,需等待 Module.onRuntimeInitialized 触发。

JS 示例:

libOpenDrive().then(Module => {
let greeter = new Module.Greeter("World");
console.log(greeter.greet());
});

4. -s EXPORT_NAME='\\"libOpenDrive\\"'

含义:

设置模块加载后的全局变量名。

加上之后:
  • 模块通过 libOpenDrive() 加载。
  • 提供更具语义化的模块名称。
去掉之后:
  • 默认模块名为 Module,可能会与其他模块冲突。

JS 示例:

libOpenDrive().then(Module => {
let greeter = new Module.Greeter("World");
console.log(greeter.greet());
});

5. -s EXPORTED_RUNTIME_METHODS='[\\"cwrap\\"]'

含义:

启用某些运行时工具函数,如 cwrap。

加上之后:
  • 可以使用 Module.cwrap 包装 C 函数,便于在 JS 中调用。
去掉之后:
  • Module.cwrap 未定义,无法使用该功能。

JS 示例:

const sayHello = Module.cwrap('sayHello', 'string', ['string']);
console.log(sayHello("Alice"));

6. -s FORCE_FILESYSTEM=1

含义:

强制启用虚拟文件系统。

加上之后:
  • 可以使用 FS_createDataFile 等文件系统 API。
去掉之后:
  • 文件系统相关操作可能失败。

JS 示例:

Module.FS_createDataFile(".", "hello.txt", "This is a test file.", true, true);
console.log(Module.FS.readFile("/hello.txt", { encoding: 'utf8' }));

7. -s ALLOW_MEMORY_GROWTH=1

含义:

允许 WASM 内存动态增长。

加上之后:
  • 可以分配超过默认限制的内存。
去掉之后:
  • 分配过大内存可能导致崩溃。

C++ 示例:

void* ptr = malloc(1024 * 1024 * 20); // 分配 20MB
free(ptr);

JS 示例:

let ptr = Module._malloc(1024 * 1024 * 20);
Module._free(ptr);


以上就是针对每个参数的详细说明及其对应的使用示例。你可以根据需求选择合适的参数组合来构建你的 WebAssembly 模块。

赞(0)
未经允许不得转载:网硕互联帮助中心 » libOpnedrive-CMake对ModuleOpenDrive配置参数
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!