環境変数の利用
グルーコードでは以下のコードにあるような、いくつかの環境変数が設定されるようになっている。
var env = {
"USER": "web_user",
"LOGNAME": "web_user",
"PATH": "/",
"PWD": "/",
"HOME": "/home/web_user",
"LANG": lang,
"_": getExecutableName()
};
これらは C++ の getenv 関数で取得できる。
また、preRun 実行時に ENV の値を設定することで、アプリケーションに独自の値を JavaScript から C++ に渡すことができる。
以下は環境変数に関して実行したファイルの一覧になる。
C:\wasm\project\13-envvar\.vscode\launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "localhost:8080",
"url": "http://localhost:8080/",
}
]
}
C:\wasm\project\13-envvar\CMakePresets.json
{
"version": 5,
"cmakeMinimumRequired": {
"major": 3,
"minor": 20,
"patch": 0
},
"configurePresets": [
{
"name": "wasm-config",
"hidden": true,
"generator": "Ninja Multi-Config",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_CXX_STANDARD": "17",
"CMAKE_CXX_STANDARD_REQUIRED": "ON",
"CMAKE_CXX_EXTENSIONS": "OFF",
"CMAKE_TOOLCHAIN_FILE": "$env{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_CONFIGURATION_TYPES": "Debug;Release"
}
},
{
"name": "wasm-config-debug",
"inherits": "wasm-config",
"cacheVariables": {
}
},
{
"name": "wasm-config-release",
"inherits": "wasm-config",
"cacheVariables": {
}
}
],
"buildPresets": [
{
"name": "wasm-build-debug",
"configurePreset": "wasm-config-debug",
"verbose": true,
"configuration": "Debug"
},
{
"name": "wasm-build-release",
"configurePreset": "wasm-config-release",
"verbose": true,
"configuration": "Release"
}
]
}
C:\wasm\project\13-envvar\CMakeLists.txt
JavaScript で ENV を利用するので、エクスポートが必要になる
cmake_minimum_required(VERSION 3.20)
project(13_envvar LANGUAGES CXX)
add_executable(13_envvar main.cpp)
target_link_options(13_envvar PRIVATE
$<$<CONFIG:Debug>:-gsource-map -sASSERTIONS=1 -sSAFE_HEAP=1>
"-sEXPORTED_RUNTIME_METHODS=ENV"
"-sEXPORT_ES6"
)
C:\wasm\project\13-envvar\index.html
preRun の実行時に APP_LOCATION というキーで値を設定
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8"/>
<script type="module">
import Module from './build/Debug/13_envvar.js';
let v = 0;
const moduleArgs = {
arguments: ['environment', 'variables'],
preRun: [
emsModule => {
emsModule.ENV['APP_LOCATION'] = window.location.href;
},
]
};
await Module(moduleArgs).then(emsModule =>
{
v = emsModule._increment(v);
console.log(`return=${v}`);
});
</script>
</head>
<body>
</body>
</html>
C:\wasm\project\13-envvar\main.cpp
一覧を取得するには environ という変数の外部宣言が必要
// UTF-8N CRLF
#include <emscripten.h>
#include <iostream>
#include <fstream>
extern "C"
EMSCRIPTEN_KEEPALIVE
int increment(int v)
{
printf("-- increment(%d)\n", v);
return v + 1;
}
extern "C" char** environ;
int main(int argc, char** argv, char** envp)
{
std::cout << "C++ main(argc=" << argc << ", argv=[";
for (int i=0; i<argc; ++i)
{
if (i) {
std::cout << ",";
}
std::cout << "'" << argv[i] << "'";
}
std::cout << "])" << std::endl;
if (envp)
{
std::cout << "envp is not null" << std::endl;
}
else
{
std::cout << "envp is null" << std::endl;
}
std::cout << "environ=[";
for (char** p=environ; *p; ++p)
{
if (p != environ) {
std::cout << ",";
}
std::cout << "'" << *p << "'";
}
std::cout << "]" << std::endl;
std::cout << "from index.html: " << getenv("APP_LOCATION") << std::endl;
return 0;
}
// EOF
実行結果
- getenv により index.html で設定した値が取得できている
- environ 変数からは一覧が取得できる
C++ main(argc=3, argv=['./this.program','environment','variables'])
envp is null
environ=['USER=web_user','LOGNAME=web_user','PATH=/','PWD=/','HOME=/home/web_user','LANG=ja.UTF-8','_=./this.program','APP_LOCATION=http://localhost:8080/']
from index.html: http://localhost:8080/
-- increment(0)
return=1
次 は Node.js 環境でデバッグを試してみる。