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.)