Emscripten을 사용하여 브라우저에서 네이티브 C/C++ 코드 실행
5583 단어 cppemscriptenwebassemblyc
WebAssembly/JS에 네이티브 코드 빌드
bmfdec을 복제하고 프로젝트를
wasm
로 컴파일하는 방법에 대해 Emscriptendocumentation을 따랐습니다. 건물bmfdec은 Emscripten 컴파일러를 사용하여 간단했습니다.emcc bmfdec/bmf2mof.c -o bmf2mof.js
하지만 한 가지 문제가 있었는데, bmfdec은 stdin에서 이진 파일로 입력을 받도록 작성되었습니다.
bmfdec.c
를 수정하고 main()
함수를 변경하여 stdin에서 바이너리를 읽는 대신 버퍼를 가져와서 parse_data()
라고 불렀습니다.int parse_data(uint8_t *pin, ssize_t lin) {
static char pout[0x40000];
int lout;
if (lin < 0) {
fprintf(stderr, "Failed to read data: %s\n", strerror(errno));
return 1;
} else if (lin == sizeof(pin)) {
fprintf(stderr, "Failed to read data: %s\n", strerror(EFBIG));
return 1;
}
if (lin <= 16 || ((uint32_t*)pin)[0] != 0x424D4F46 || ((uint32_t*)pin)[1] != 0x01 || ((uint32_t*)pin)[2] != (uint32_t)lin-16 || ((uint32_t*)pin)[3] > sizeof(pout)) {
fprintf(stderr, "Invalid input\n");
return 1;
}
lout = ((uint32_t*)pin)[3];
if (ds_dec((char *)pin+16, lin-16, pout, lout, 0) != lout) {
fprintf(stderr, "Decompress failed\n");
return 1;
}
return process_data(pout, lout);
}
네이티브 함수를 JavaScript로 내보내기
JavaScript 내에서 C 함수를 호출할 수 있으려면 일부 추가 플래그로 컴파일
bmf2mof
하여 모듈화하고 심볼을 JS 출력 파일로 내보내야 합니다.MODULARIZE
컴파일러 플래그를 사용하면 생성된 JavaScript가 Node.js에서 약속 및 require()
를 사용할 수 있는 모듈식으로 만들어집니다. EXPORT_NAME='bmf2mof'
컴파일러 플래그는 내보낸 모듈 이름을 변경합니다. 이 경우 이름은 bmf2mof()
입니다. WASM=1
는 wasm 출력을 원한다고 지정합니다. 마지막으로 "EXPORTED_FUNCTIONS=['_parse_data']"
는 C 코드에서 함수parse_data
를 내보냅니다. 우리는 또한 optimize 출력 JS 코드를 원하므로 -O2
를 사용할 것입니다.emcc bmfdec/bmf2mof.c -s "EXPORTED_FUNCTIONS=['_parse_data']" -s "MODULARIZE=1" -s "EXPORT_NAME='bmf2mof'" -s "WASM=1" -O2 -o bmf2mof.js
이제 생성된
bmf2mof.js
에는 C 함수에 매핑되고 JavaScript 코드에서 호출할 수 있는 _parse_data
함수가 있습니다.const bmf2mof = require('bmf2mof.js')
const buf = new Uint8Array([0x46, 0x4F, 0x4D, 0x42, ..., 0x20, 0xEC, 0xFF, 0x0F])
bmf2mof().then(instance => {
function arrayToPtr(array) {
var ptr = instance._malloc(array.length)
instance.HEAPU8.set(array, ptr)
return ptr
}
instance._parse_data(arrayToPtr(buf), buf.length)
})
모든 것이 예상대로 작동하고 위의 코드
node [filename].js
를 실행하면 데이터가 표준 출력으로 출력됩니다. 그러나 이것을 브라우저에서 사용하려는 경우 출력이 콘솔로 이동합니다. 따라서 출력을 포착하고 원하는 위치로 리디렉션하는 방법을 찾아야 합니다. 이 경우에는 WMIDumpper 의 텍스트 영역이 됩니다.생성된 JS 파일에 관해서는 Emscripten 문서가 약간 부족했기 때문에 그것이 무엇을 하는지 이해하기 위해 시간을 들였습니다. 생성된 JS는 C/C++에서 JS로의 매핑을 처리하기 위해 몇 가지 기본 함수를 정의하는 것으로 나타났습니다. 예를 들어,
printErr
에 바인딩하는 console.warn
함수를 정의합니다. 이는 stderr로 인쇄하는 C/C++ 코드가 JS에서 console.warn
를 사용할 것임을 의미합니다. 자세한 기술 정보는 Create the Module object을 참조하십시오.생성된 JS는 기본 모듈 기능을 재정의하는 객체를 사용합니다. 출력을 stdout에서 HTML의 텍스트 영역으로 리디렉션하려면 자체 함수
print
를 정의하기만 하면 됩니다.const textarea = document.getElementById('textarea')
bmf2mof({
print: function (text) {
textarea.value += text + '\n'
}
}).then(instance => ...)
물론 브라우저에서 이 코드를 사용하려면 먼저 HTML에서 생성된 JS 스크립트를 소싱해야 합니다.
참조
bmfdec에서 bmf2mof.wasm의 WebAssembly 분기 버전을 찾을 수 있습니다.
WMIDumpper은 wmidump과 bmfdec의 웹 클론일 뿐이므로 iksaif과 pali의 멋진 작업에 찬사를 보냅니다.
Reference
이 문제에 관하여(Emscripten을 사용하여 브라우저에서 네이티브 C/C++ 코드 실행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/aymanbagabas/run-native-cc-code-in-the-browser-using-emscripten-2574텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)