GCC를 사용한 실행 파일에 리소스 내장
GCC가 컴파일한 C/C++ 어플리케이션에 외부 바이너리 데이터를 쉽게 삽입할 수 있는 방법을 찾고 있습니다.
일의 예가 셰이더 입니다. - 셰이더 코드를 다루면 됩니다. - 셰이더 코드를 소스 됩니다.const char* shader = "source here";
하지만 그건 매우 비현실적입니다.
컴파일러가 대신했으면 합니다.컴파일(컴파일 스테이지)에서 파일 "foo.bar"을 읽고 그 콘텐츠를 제 프로그램에 링크하여 코드에서 바이너리 데이터로 액세스할 수 있도록 합니다.
단일 .exe 파일로 배포하고 싶은 소규모 응용 프로그램에 유용합니다.
GCC는 이와 같은 기능을 지원합니까?
몇 가지 가능성이 있습니다.
ld의 기능을 사용하여 임의의 파일을 오브젝트로 변환합니다(gcc mingw를 사용하여 바이너리블롭을 포함).
ld -r -b binary -o binary.o foo.bar # then link in binary.o
bin2c
/bin2h
파일을 바이트 배열로 변환하는 유틸리티(리소스 섹션이나 외부 이미지를 사용하지 않고 코드에 이미지를 포함)
음음 using of음음음음음음 using using using update update update update update update update update update update update update update update update update update update update update update update update update update update update update update update update update update update update update update update 。ld -r -b binary
:
#include <stdio.h>
// a file named foo.bar with some example text is 'imported' into
// an object file using the following command:
//
// ld -r -b binary -o foo.bar.o foo.bar
//
// That creates an bject file named "foo.bar.o" with the following
// symbols:
//
// _binary_foo_bar_start
// _binary_foo_bar_end
// _binary_foo_bar_size
//
// Note that the symbols are addresses (so for example, to get the
// size value, you have to get the address of the _binary_foo_bar_size
// symbol).
//
// In my example, foo.bar is a simple text file, and this program will
// dump the contents of that file which has been linked in by specifying
// foo.bar.o as an object file input to the linker when the progrma is built
extern char _binary_foo_bar_start[];
extern char _binary_foo_bar_end[];
int main(void)
{
printf( "address of start: %p\n", &_binary_foo_bar_start);
printf( "address of end: %p\n", &_binary_foo_bar_end);
for (char* p = _binary_foo_bar_start; p != _binary_foo_bar_end; ++p) {
putchar( *p);
}
return 0;
}
- 2 - 2 - 올바르게 읽을 수 ._foo_foo_bar_size로 설정합니다.시 .display (unsigned int)&_binary_foo_bar_size
그러나 이 값을 변수에 할당하면 항상 잘못된 값이 지정됩니다.는 이 를 다음과 할 수 있습니다.
unsigned int iSize = (unsigned int)(&_binary_foo_bar_end - &_binary_foo_bar_start)
이것은 회피책이지만 효과가 있고 너무 못생기지 않습니다.
이 작업에는 GAS 디렉티브를 사용할 수 있습니다.여기 완전 무료 라이선스 라이브러리가 있습니다.
https://github.com/graphitemaster/incbin
재점검하다.인빈 방식은 이렇습니다.gcc -c thing을 사용하여 컴파일한 .의 어셈블리파일이 있습니다.
.section .rodata
.global thing
.type thing, @object
.align 4
thing:
.incbin "meh.bin"
thing_end:
.global thing_size
.type thing_size, @object
.align 4
thing_size:
.int thing_end - thing
c 또는 cpp 코드로 참조할 수 있는 것은 다음과 같습니다.
extern const char thing[];
extern const char* thing_end;
extern int thing_size;
그런 다음 결과물인 .o를 다른 컴파일 유닛과 연결합니다.@John Ripley의 답변은 다음과 같습니다.C/C++ with GCC: 자원 파일을 실행 파일/라이브러리에 정적으로 추가합니다.
그러나 위의 내용은 inbin이 제공하는 것만큼 편리하지 않습니다.incbin을 사용하여 위의 작업을 수행하기 위해 어셈블러를 작성할 필요가 없습니다.다음 사항만 있으면 됩니다.
#include "incbin.h"
INCBIN(thing, "meh.bin");
int main(int argc, char* argv[])
{
// Now use thing
printf("thing=%p\n", gThingData);
printf("thing len=%d\n", gThingSize);
}
앞서 설명한 제안과 마찬가지로 Linux에서는 C 헤더 파일을 생성하는 기능이 있는 16진수 덤프 도구 xxd를 사용할 수 있습니다.
xxd -i mybinary > myheader.h
이것은 헤더 파일로 실행할 수 있습니다.
#ifndef SHADER_SRC_HPP
#define SHADER_SRC_HPP
const char* shader= "
//source
";
#endif
그것도 포함해서요.
다른 방법은 셰이더 파일을 읽는 것입니다.
정적 데이터를 실행 파일에 포함하려면 .lib/.a 파일 또는 헤더 파일에 서명되지 않은 문자 배열로 패키지합니다.휴대할 수 있는 방법을 찾고 있는 경우입니다.여기서 두 가지 작업을 모두 수행할 수 있는 명령줄 도구를 만들었습니다.파일을 나열하고 옵션 -l64를 선택하면 각 데이터에 대한 모든 포인터가 포함된 헤더와 함께 64비트 라이브러리 파일을 출력할 수 있습니다.
더 많은 옵션을 살펴볼 수도 있습니다.예를 들어, 이 옵션은 다음과 같습니다.
>BinPack image.png -j -hx
이미지의 데이터를 출력합니다.-j 옵션에 따라 16진수 및 행으로 png을 헤더 파일로 지정합니다.
const unsigned char BP_icon[] = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x01,0xed,0x00,0x00,0x01,0xed,0x08,0x06,0x00,0x00,0x00,0x34,0xb4,0x26,
0xfb,0x00,0x00,0x02,0xf1,0x7a,0x54,0x58,0x74,0x52,0x61,0x77,0x20,0x70,0x72,0x6f,
0x66,0x69,0x6c,0x65,0x20,0x74,0x79,0x70,0x65,0x20,0x65,0x78,0x69,0x66,0x00,0x00,
0x78,0xda,0xed,0x96,0x5d,0x92,0xe3,0x2a,0x0c,0x85,0xdf,0x59,0xc5,0x2c,0x01,0x49,
0x08,0x89,0xe5,0x60,0x7e,0xaa,0xee,0x0e,0xee,0xf2,0xef,0x01,0x3b,0x9e,0x4e,0xba,
0xbb,0x6a,0xa6,0x66,0x5e,0x6e,0x55,0x4c,0x8c,0x88,0x0c,0x07,0xd0,0x27,0x93,0x84,
0xf1,0xef,0x3f,0x33,0xfc,0xc0,0x45,0xc5,0x52,0x48,0x6a,0x9e,0x4b,0xce,0x11,0x57,
0x2a,0xa9,0x70,0x45,0xc3,0xe3,0x79,0xd5,0x5d,0x53,0x4c,0xbb,0xde,0xd7,0xe8,0x57,
0x8b,0x9e,0xfd,0xe1,0x7e,0xc0,0xb0,0x02,0x2b,0xe7,0x03,0xcf,0xa7,0xa5,0x87,0xff,
0x1a,0xf0,0xb0,0x54,0xd1,0xd2,0x0f,0x42,0xde,0xae,0x07,0xc7,0xf3,0x83,0x92,0x4e,
0xcb,0xfe,0x22,0xc4,0xa7,0x91,0xb5,0xa2,0xd5,0xee,0x97,0x50,0xb9,0x84,0x84,0xcf,
0x07,0x74,0x09,0xd4,0x73,0x5b,0x31,0x17,0xb7,0x8f,0x5b,0x38,0xc6,0x69,0xaf}
언급URL : https://stackoverflow.com/questions/4158900/embedding-resources-in-executable-using-gcc
'IT이야기' 카테고리의 다른 글
Serializable Interface는 언제 구현해야 합니까? (0) | 2022.06.07 |
---|---|
Vuex에 액세스하여 vue 라우터의 모듈 getter를 지연시켰습니다. (0) | 2022.06.07 |
Vuex 스토어에서 모듈 액세스 (0) | 2022.06.06 |
Java에서 XML을 예쁘게 인쇄하는 방법 (0) | 2022.06.06 |
Windows(Visual C)용 unistd.h를 대체할 수 있는 것이 있습니까? (0) | 2022.06.06 |