이게 뭐야?
이것은 Apple IIgs 소프트웨어를 리버스 엔지니어링하기 위해 특별히 설계된 명령 줄 도구 세트입니다. 2 개의 별도 도구로 구성됩니다. 및 . 첫 번째는 디스크 이미지를 추출하는 간단한 도구이고 위치로 진입 점 두 번째는 실행 파일을 분해하고 API 정보를 쿼리 할 수있는 더 복잡한 도구입니다.
.2mg 및 .po prodos 디스크 이미지를 추출합니다. 디스크 이미지 파일 이름을 지정하면 디스크 이름으로 폴더가 생성되고 적절한 계층 구조로 모든 파일이 해당 폴더에 추출됩니다.
또는 명령 줄 인수로 디스크 이미지의 내용을 나열하는 데 사용할 수도 있습니다 . 파일을 나열하면 생성 날짜 및 파일 유형과 같은 각 파일과 관련된 메타 데이터도 제공됩니다.
두 개의 분해 도구의 조합입니다. 원시 바이너리 파일을 분해하고 OMF 파일 (예 : sys16 또는 도구 파일)을 분해 할 수 있으며 Apple IIgs API를 검사하는 데 사용할 수 있습니다.
추적 디스어셈블러이므로 주어진 진입 점에서 디스 어셈블리를 시작하고 가능한 모든 경로를 따릅니다. 분해되지 않은 모든 것은 데이터로 간주되며 16 진 덤프로 표시됩니다.
처음으로 특정 파일을 분해하는 데 사용 되며 자동 감지 된 정보가 있는 파일을 생성합니다 .
regs 명령 줄 인수
분해를 사용자 정의하는 데 사용할 수있는 몇 가지 플래그가 있습니다. OMF 파일을 디스 어셈블하는 경우 이러한 플래그는 아무것도 수행하지 않습니다. OMF 파일이이 정보를 대체합니다.
이러한 플래그는 실제로 초기 분해에만 유용합니다. 한 번 파일이 생성되고, 해당 특정 파일의 분해 모두의 미래를 사용자 정의 할 것을 사용해야합니다.
일반 바이너리 실행 파일의 경우 또는 플래그를 사용하여로드해야하는 메모리 위치를 지정할 수 있습니다 . 앞에 오는 경우 전달 주소 진수 또는 16 진수에있을 수 있습니다 또는 . 를 사용하는 경우 인수를 작은 따옴표로 묶어야합니다 . 그렇지 않으면 쉘에서 변수로 해석합니다. 이 주소는 실행 파일의 진입 점으로도 사용됩니다.
플래그 를 사용하여 디스어셈블러가 에뮬레이션 모드에서 시작되도록 할 수 있습니다 . 기본적으로 디스어셈블러는 기본 모드에서 시작됩니다. 디스어셈블러가 '-m'이있는 8 비트 누산기를 사용하고 '-x'가있는 8 비트 인덱스를 사용하도록 강제 할 수 있습니다. 그러나 에뮬레이션 모드는 실제 하드웨어에서와 마찬가지로 이미 두 플래그를 모두 가정합니다.
아래에 설명 된대로 API 쿼리에 사용되는 플래그 도 있습니다.
.regs 파일
앞서 언급했듯이 디스어셈블러를 처음 실행하면 주어진 실행 파일에 대한 파일 이 생성 됩니다. 이 파일의 형식은 상당히 전면적이고 분해를 추가로 사용자 정의 할 수 있습니다.
이 파일의 각 줄은 주소로 시작합니다. 이 주소는 달러 기호 와 은행 구분선 이 모두 선택 사항 인 형식입니다.
주소 뒤에 느낌표가 있으면 이 주소가 실행 파일이로드되는 메모리의 지점으로 사용됨을 의미합니다. (OMF 파일은 이것을 무시합니다). 둘 이상의 주소 뒤에 느낌표가 오는 경우 처음 발견 된 주소 만 사용됩니다.
주소 뒤에 콜론이 오면 이 주소가 진입 점으로 간주됨을 의미합니다. 이 주소에서 분해가 시작됩니다. 원하는만큼 많은 진입 점이있을 수 있습니다. 실제로 파일을 분해 할 때 간접 점프로 위치로 진입 점 인해 분해가 중지되는 것을 알 수 있습니다. 파일에 진입 점을 추가 하여 해당 점프의 대상에서 디스 어셈블리를 계속할 수 있습니다 .
콜론 뒤에는 선택적으로 "e" "m", "x"또는 이러한 문자의 조합을 지정하여 해당 진입 점에서 디스 어셈블이 시작될 때 디스어셈블러 상태를 강제로 지정할 수 있습니다.
마지막으로 주소 뒤에 angle-bracket이 오면 이 주소는 기호 이름을가집니다. 기호 위치로 진입 점 이름은 닫는 꺾쇠 괄호로 끝나야 합니다. 주소에 기호 이름이있는 경우 디스 어셈블리에 나타날 때마다 주소 대신이 이름이 사용됩니다.
주소 다음에는 앞의 모든 마커가 올 수 있습니다. 예를 들어 진입 점이기도 한에 로드 된 실행 파일이 있고 에뮬레이션 모드에서 시작하고 진입 점에 의미있는 이름을 지정하려고한다고 가정합니다. 이것은 매우 일반적인 시나리오이며 한 줄로 된 파일 이 생성됩니다 .
뱅크 디바이더가 필요하지 않았기 때문에 (뱅크는 당연히 0이 됨) 생략했고 'm'및 'x'플래그는 에뮬레이션 모드에서 항상 켜져 있으므로 포함 할 필요가 없습니다.
형식이 표준화되고 주소가 당신을 위해 자동으로 정렬 할 수 있도록 파일은 실제로 당신이 디스어셈블러를 실행할 때마다 다시 작성됩니다.
워크 플로우
다른 디스어셈블러에 익숙한 지 확실하지 않을 수 있으므로이 디스어셈블러의 워크 플로는 지속적으로 반복됩니다. 실행 파일에서 디스어셈블러를 실행 한 다음 파일을 조정하여 필요에 따라 진입 점을 추가하고 용도를 식별 할 때 메모리 주소에 기호를 추가합니다. 그런 다음 매번 디스어셈블러를 다시 실행하십시오. 최종 결과는 더 깨끗하고 명확하고 따라하기 쉬운 분해입니다.
분해 표기
의 분해 스타일에 대해 유의해야 할 사항이 거의 없습니다 . 첫 번째는 코드 흐름을 추적했기 때문에 분기 대상 앞에 최대 7 개의 소스 주소를 표시하고 현재 행의 위 또는 아래에 있는지 여부를 표시하는 행이옵니다. 이것은 코드 흐름을 파악하는 데 도움이됩니다.
다음은 다음과 같은 도구 호출 이 지침으로 표시 된다는 것 입니다. 이것은 분해를 극적으로 정리하는 데 도움이됩니다. 도구 번호와 함께 X를로드하는 코드를 표시 한 다음 도구 디스패치 주소로 점프하는 대신 호출 된 도구의 이름으로 모두 대체합니다. 이것은 아래에 설명 된 iigs 폴더의 지문에 의해 제어됩니다.
마지막으로 가장 특이한 점은 주소 지정이 DBR 및 Direct 모드를 사용할 때 "B :"및 "D :"플래그를 포함한다는 것입니다. 이는 IIgs가 직접 페이지 및 DBR 레지스터를 변경할 수 있으므로 해당 주소가 정확하다고 믿을 수 없기 때문입니다.
주소가 "B :"로 시작하면 DBR 레지스터의 현재 값을 주소에 추가해야합니다. 주소가 "D :"로 시작하면 직접 레지스터의 현재 값을 주소에 추가해야합니다.
오해의 소지가있을 수 있으므로 해당 주소에서 심볼 스와핑을 수행하지 않습니다. 대신 일치하는 기호가 같은 줄에 주석으로 포함됩니다. 이렇게하면 IIgs가 표준 설정에있는 경우 해당 주소가 무엇을 나타내는 지 알 수 있으며 그렇지 않은 경우 주석을 무시할 수 있습니다.
Docmaker, API 및 iigs 폴더
Apple IIgs API와 관련된 구조 및 기능 정의가 포함 된 텍스트 파일이 포함 된 iigs 폴더를 볼 수 있습니다. 이러한 파일은 두 가지 목적으로 구문 분석되고 프로그램으로 컴파일 됩니다.
첫째, 함수에는 디스어셈블러가 프로그램이 해당 함수를 호출하는시기를 식별하고 시스템 호출을 실제 함수 이름으로 대체하는 데 사용할 수있는 지문이 첨부되어 있습니다.
둘째, 주어진 구조 또는 함수를 쿼리 하고 필드 오프셋을 계산하도록 할 수도 있습니다. 이것은 분해에 도움이 될 것입니다.
Docmaker는 전체 디렉토리를 읽고 컴파일 할 때 포함되는 데이터 파일을 생성하는 프로그램입니다 .
API 쿼리
API 쿼리는 매우 간단 합니다. 플래그 와 키워드를 사용하여 호출 합니다. 플래그가 포함 된 경우 분해 할 파일을 제공 할 필요가 없습니다 . 그런 다음 Regs는 해당 키워드가 포함 된 데이터 유형 또는 함수에 대한 API를 검색하고 이에 대한 정보를 출력합니다.
구조를 쿼리하는 경우 또는 플래그를 사용하여 구조가 시작되어야하는 램의 위치를 지정할 수도 있으며 각 필드에 대해 계산 된 오프셋이 포함됩니다.
예를 들어, 디스 어셈블하는 프로그램이 호출을 하고 그 값 을 함수에 전달 한다고 가정합니다. 다음을 수행 할 수 있습니다.
이것은 유형의 단일 인수를 취한다는 것을 알 수 있습니다 . 쿼리를 통해 .NET에 대한 이중 포인터임을 확인할 수 있습니다 . 다음으로 할 수 있습니다.
이제 해당 메모리 주소의 변수가 무엇인지 정확히 알고 있으며, 이는 더 나아가 분해에 도움이 될 수 있습니다. 나중에 디스 어셈블리를 위해 필드를 파일의 기호로 다시 추가 할 수도 있습니다 .
이러한 도구의 유연성으로 인해 사용이 약간 복잡해집니다. 그래서 여기에 다양한 것들을 분해하는 방법에 대한 몇 가지 예가 있습니다.
S16 분해
드림 존의 S16을 예로 들어 보겠습니다. 초기지도 생성 및 첫 번째 분해 :
이렇게하면 (사용되지 않은) 조직 주소가 인 dream.sys16.regs 파일이 생성 되고 진입 점이 . 또한에서 까지 5 개의 파일을 생성 합니다 . 이것은 S16의 각 세그먼트에 대한 분해입니다.
seg1 디스 어셈블리를 살펴보면 또는 같은 도구를 호출 한 후 누산기가 . 나는 이것이 toolErr 변수라는 것을 경험으로 알고 있습니다. 따라서 나중에 코드가 검사 할 경우 어떤 일이 발생하는지 알 수 있도록 심볼을 추가해 보겠습니다. dream.sys16.regs를 편집하고 다음 줄을 추가합니다.
다시 실행 하면 이제 디스 어셈블리가 toolErr을 올바르게 참조합니다.
실제 프로젝트에서는 수백 또는 수천 개의 기호를 추가하게됩니다. 도구는이를 위해 설계되었습니다.
도구 분해
이것은 S16을 분해하는 것과 동일하지만 중요한 차이점이 있습니다.
우리는 진입 점없이 시작하고 싶습니다. 빈 파일 을 만들어이를 수행 할 수 있습니다 . 그런 다음 도구 파일에서 regs를 실행하십시오.
진입 점이 없으면 전체 파일은 16 진 덤프 일뿐입니다. 그러나 이는 세그먼트 콘텐츠의 16 진 덤프이므로 OMF에서 발견되는 모든 오버 헤드 및 형식 정보가 누락되었습니다. 그렇기 때문에 원래 도구 파일을 16 진수로 덤프 할 수 없습니다.
모든 도구는 도구 테이블에서 시작합니다. 첫 번째 dword는이 파일의 도구 수를 지정합니다. 다음 dword에는 다양한 도구 진입 점의 반환 주소가 포함됩니다.
분해하고 싶다고합시다 . 실행 하면 $ 19 도구 세트 내의 $ 0b 도구임을 알 수 있습니다. 10 진수로 변환하여 TOOL025 파일 (이미 사용하기 시작한 동일한 파일, 얼마나 편리함)에 있는지 확인하십시오. $ 0b 도구에 대한 오프셋을 계산할 수 있습니다.
우리 는 도구 세트가 분해되는 곳이기 때문에 . 해당 오프셋으로 돌아 가면 주소에 대한 리틀 엔디안 인 "99 02 01 00"이 표시 됩니다. 이것들은 반환 주소이기 때문에 실제 진입 점을 얻기 위해 그것을 증가시켜야합니다 .
해당 진입 점을 파일에 추가 하십시오.
regs를 다시 실행하십시오. seg1을 다시 확인하고 아래에서 기능에 대한 분해가 완료되었습니다 .
ROM에서 특정 도구 호출 분해
WriteRamBlock을 분해하고 싶다고 가정 해 보겠습니다. 도구 세트 8의 도구 9임을 보여줍니다. 검색하면 패치가 적용되지 않은 도구 세트이기 때문에 어디에도 TOOL008이 없다는 것을 알게 될 것입니다. 대신 ROM에서 직접 분해해야합니다. 더 익숙하기 때문에 128k ROM01을 사용할 것입니다. 대신 ROM00 또는 ROM03을 사용할 수 있습니다. 단지 사물의 위치가 다를뿐입니다.
가장 먼저 할 일은 실제로 ROM 용 파일을 직접 만드는 것 입니다.
128k ROM이 메모리에로드되어야하고 도구 부트 스트랩도 해당 주소에 있다는 것을 알고 있기 때문입니다. ROM03의 경우 ROM을 . 도구 부트 스트랩은 bank에서 디스패치를 초기화합니다 . 코드 는 기본 도구 디스패치 인 에서 로 16 바이트를 복사 합니다. 해당 진입 점을 추가하고 다시 분해 해 보겠습니다.
이 디스패치 코드를 단계별로 살펴보면 먼저의 테이블에서 도구 세트를 찾습니다 . 툴셋 $ 08 이후이므로 오프셋을 계산합니다 : . 주소의 리틀 엔디안 표현 인 "00 3e ff 00"위치에서 볼 수 있습니다 .
그런 다음 디스패치 코드는 해당 주소의 다른 테이블을 사용하여 원하는 도구 진입 점의 반환 주소를 결정합니다. WriteRamBlock은 도구 9이므로 오프셋을 새 테이블로 계산합니다 .
그 위치에 "a4 41 ff 00"값이 있지만 반환 주소이므로 분해하기 전에 값을 늘려야합니다.
Boom, 우리는 ROM에서 발견 된 특정 도구 호출을 분해했습니다.
간단한 ProDOS 실행 파일 분해
ProDOS 바이너리는 재배치 할 수 없으며 RAM에서로드해야하는 위치를 지정하는 내부에 아무것도 없습니다. 그러나 파일 시스템 자체에는 해당 정보가 있습니다.
또는 인수 와 함께 사용 하면 파일과 관련된 메타 데이터와 함께 파일 목록이 제공됩니다. 예를 들어 봅시다 .
당신은 그 볼 의 종류가 와의 auxtype , 그리고 는 "SYS / ProDOS 시스템 파일"등의 식별을. 이것은 실제로 간단한 실행 파일입니다.
aux 유형은 RAM에서이 실행 파일을로드 할 위치를 지정합니다. 이 경우 .
또한 이러한 실행 파일은 실제로 8 비트 실행 파일이기 때문에 에뮬레이션 모드에서 디스 어셈블리를 시작해야합니다.
이 모든 정보를 사용하여이 파일을 분해 할 수 있습니다.
이것은 regs에게 8 비트 누산기 및 인덱스를 사용하여 에뮬레이션 모드에서 시작하고 분해하기 전에 파일을로드하도록 지시 합니다.
OMF 파일이 아니기 때문에 출력 파일 . 그러나 원할 경우 기호와 대체 진입 점을 추가 할 수 있도록 파일이 여전히 있다는 점에 유의하십시오 (달리 지시하지 않는 한 regs는 기본 모드로 기본 설정되므로 대체 진입 점에 'e'플래그를 포함해야합니다).
Linux 커널 Start_kernel 진입점? 즉시 애플리케이션 수정
지난 몇 주 동안 일부 사용자는 linux 커널의 start_kernel 진입점에서 알려진 모든 오류 코드를 접했습니다. . 이 문제는 여러 요인으로 인해 발생합니다. 우리는 이것을 아래에서 검토할 것입니다.남편과 나는 여러 번 아치/데이터베이스로 돌아가지만 start_kernel은 아마도 일반적이고 아키텍처에 독립적인 커널 코드 항목일 것입니다. start_kernel 함수 내부를 살펴보면 이 함수가 환상적이라는 것을 확실히 알 수 있습니다. 현재 약 90개의 함수 호출로 구성되어 있습니다.
커널 진입점 이전의 최종 준비 부분인 특정 이전 부분을 모두 읽었다면 초기화 전에 거의 모든 작업을 완료하고 커널만 중지했다는 것을 기억할 수도 있습니다. ‘ start_kernel 호출은 init/main.c에서 기능을 유지합니다. start_kernel 은 전체 스타일에 독립적인 커널 법칙 항목의 일부가 될 것이지만 arch/ 폴더를 점점 더 많이 적용하고 있습니다. start_kernel 함수를 살펴보면 이 함수가 상당히 큰 것을 알 수 있습니다. 현재 86 노력 호출이 포함되어 있습니다. 예, 그는 일반적으로 이 기술에 나타나는 모든 프로세스를 작동시키지 않는 특히 광범위하고 특정한 측면을 제공합니다. 현재로서는 이것을 사용하여 시작해야 합니다. 이 부분과 그 직후의 모든 부분은 일반적으로 “커널 초기화 프로세스” 장에서 확실히 다룹니다.
start_kernel 의 유일한 목적은 커널 초기화 프로세스를 건너뛰고 일부 초기 init 프로세스를 시작하는 것입니다. 초기 프로세스를 시작하기 위치로 진입 점 전에 start_kernel 은 다음과 같은 많은 작업을 실행하는 데 필요합니다. 다른 캐시. vfs에서 일반적으로 메모리 관리자, rcu, vmalloc, 스케줄러, IRQ, ACPI 등을 성공적으로 초기화합니다. 이 단계를 완료해야만 누구나 이 종류의 장의 마지막 부분에서 원래 init 작업의 시작 부분을 볼 수 있습니다. 커널 코드가 너무 많아서 시작하겠습니다. 모두
참고. Linux 커널 초기화 프로세스 에 있는 이 큰 단계의 요소도 디버깅을 위해 아무 것도 하지 않습니다. 정보에는 커널 디버깅에 대한 팁을 사용하는 별도의 장이 있습니다.
속성에 대한 간략한 정보
누가 진입점 커널 시스템으로 작동합니까?
앞서 언급했듯이 main()은 각 로더 실행 파일에 대한 입력 객체로 실행됩니다. 그러나 하중 과정에 대해 다른 항목을 형성할 수 있습니다. 기본적으로 좋아하는 DLL로 이동과 같은 여러 정확한 진입점을 정의할 수 있습니다.
위에서 작성한 함수처럼 start_kernel 함수는 init/main.c 파일에 확실히 정의되어 있습니다. 이 작업은 __init 속성으로 정의되며 그 외에도 이미 많은 부분에서 이 속성으로 정의할 수 있는 모든 기능이 이 커널을 초기화할 때 매우 중요하다는 것을 알 수 있습니다. .
현재 프로세스가 초기화를 종료한 후 커널과 연결된 이 버전은 free_initmem 를 호출하는 것 외에도 이러한 셀을 재정의합니다. 또한 __init 는 notrace 와 결합된 __cold 와 같은 둘 이상의 속성으로 구성됩니다. 일종의 cold 속성과 같은 전자의 목적은 사용자 정의 함수가 이전에 거의 소유되지 않은 사용자와 컴파일러가 해당 함수의 크기를 높여야 함을 나타내는 것입니다. 예정된 notrace 는 다음과 같이 추출됩니다.
——————— 1) 커널은 커널 데이터 구조만큼 철저하게 하드웨어를 초기화합니다. 2) 커널의 명령줄을 등록할 수 있습니다. 3) 스토리지에 대한 정보는 대부분의 BIOS에서 검색됩니다.
여기서 no_instrument_function 은 컴파일러가 새 프로파일링 호출 기능을 요청하지 않도록 지시합니다.
이 우수한 start_kernel 함수의 정의에서 실제로 다음을 얻기 위해 확장되는 __visible 속성도 볼 수 있습니다.
여기서 external_visible 은 전체 컴파일러에게 invalid 로 해당 함수/변수를 추가하는 것을 피하기 위해 내 고유의 함수나 변수를 사용하고 있음을 알려줍니다. include/linux/init.h 전체에서 이 우수한 속성 및 기타 매크로 속성의 정의를 자주 찾을 수 있습니다.
Start_kernel의 첫 번째 기본 단계
start_kernel 시작 부분에서 다음 두 변수 뒤에 있는 정의를 볼 수 있습니다.
믿을 수 없는 것은 종종 커널 명령줄에 대한 포인터이며 두 번째는 이제 parse_args 함수와 관련된 결과를 포함합니다. 이 함수는 정렬의 매개변수가 있는 문자열 형식을 취합니다. name=value parst , 특정 핵심 문구를 찾고 올바른 핸들러를 이메일로 보내십시오. 지금은 이 두 구성 요소의 이면에 있는 아이디어에 대해 이야기하지 않겠지만 이후 부분에서도 작동하는 것을 보게 될 것입니다. 모든 다음 단계에서 set_task_stack_end_magic 함수에 대한 잘 설계된 호출을 볼 수 있습니다. 이 함수는 다수의 init_task 및 STACK_END_MAGIC ( 0x57AC6E9D ) 단위의 주소를 가져와 희망 카나리아로 처리합니다. init_task 는 가장 오래된 거대한 사업 구조를 나타냅니다.
Linux 커널은 어디에서 시작합니까?
대신 웹 사이트의 /boot/grub2/i386-pc 웹 사이트 디렉토리에서 추가로 패키징된 런타임 커널 모듈과 주로 관련되어 있습니다. GRUB2의 첫 번째 또는 때로는 두 번째 수준의 기능은 훌륭한 Linux 커널을 찾아 RAM으로 완성하고 컴퓨터의 위치로 진입 점 중지를 커널로 되돌리는 것입니다. 커널 및 관련 파일은 일반적으로 /boot 디렉토리에 있습니다.
여기서 task_struct 훌륭한 소매업체는 프로세스에서 전달되는 모든 정보를 제공합니다. 이 구조는 매우 클 수 있으므로 이 책에서 다루지 않겠습니다. include/linux/sched.h에서 정의를 찾을 수 있습니다. 주어진 시간에 task_struct 는 100 개 이상의 필드를 생성했습니다! 이 책 전체에서 설명되지 않은 task_struct 설명을 고려하지 않을 수도 있지만 Linux 커널에서 일반적으로 process 가 되는 가장 중요한 기본 구조이기 때문에 which를 꽤 자주 사용할 것입니다. . 지금 우리가 실제로 마주하는 이 구조의 이러한 위치의 의미를 설명해야 할 것입니다.
INIT_TASK 매크로에 의해 초기화되는 것으로 간주되는 이 init_task 정의를 상상할 수 있습니다. 이 매크로는 .h의 /linux/init_task를 포함하고 첫 번째 프로세스에 대한 새로운 거래로 init_task 를 단순히 채웁니다. 적합한 예:
몇 분 만에 PC 속도 향상
전처럼 빠르게 실행되지 않는 컴퓨터가 있습니까? 업그레이드가 필요한 시점일 수 있습니다. Restoro는 가장 강력하고 사용하기 쉬운 PC 최적화 소프트웨어입니다. 전체 시스템을 빠르게 스캔하고 오류나 문제를 찾아 클릭 한 번으로 수정합니다. 즉, 이러한 문제를 스스로 해결하는 방법을 찾기 위해 Google에서 몇 시간을 보낼 위치로 진입 점 필요 없이 더 빠른 부팅 시간, 더 나은 성능, 더 적은 충돌이 발생합니다. 이 놀라운 수리 도구를 사용하려면 지금 여기를 클릭하십시오:
수정됨: Msvcrt Dll 진입점을 찾을 수 없음을 수정하는 방법
의심할 여지 없이 지난 며칠 동안 우리 회사 사용자 중 일부는 msvcrt dll 항목 영역을 찾을 수 없는 오류 절차를 겪었습니다. 이 문제는 실제로 많은 요인에 의해 발생합니다. 지금 확실히 검토하겠습니다.
몇 분 만에 PC를 새 것처럼 실행하세요!
MSVKRT. DLL은 MSVC(Visual C++ Compiler) 패턴 4.2~6.0을 수신하기 위한 공유 C 라이브러리입니다. 대부분의 표준 C 라이브러리 기능과 함께 모든 버전의 MSVC에서 컴파일된 아이디어를 제공합니다.
msvcrt.dll 오류는 dll 파일 msvcrt를 손상시킬 수 있는 변조로 인해 발생할 수 있습니다.
1] 프로그램을 다시 설치하십시오.2] 시스템 파일 검사기를 실행합니다.3] DLL 파일을 다시 등록합니다.4] 특정 레지스트리 클리너를 실행합니다.5] Walker에 대한 의존성을 사용하십시오.6] 이벤트 뷰어에서 진실을 확인하세요.관련 자료: 인터넷 스트리밍 dll 파일 충돌 보고 시 오류 수정.
일부 범죄에서 msvcrt.dll 오류는 각 레지스트리 문제, 바이러스 또는 기타 스파이웨어 및 애드웨어, 또는 기껏해야 이 하드웨어 오류를 나타낼 수 있습니다.
Msvcrt.dll 오류
Msvcrt DLL 오류를 어떻게 수정합니까?
msvcrt를 복원합니다.Microsoft 웹 사이트에서 Visual Studio용 특정 Visual C++ 재배포 가능 패키지를 다운로드하여 설치합니다.msvcrt를 사용하는 루틴을 다시 설치하십시오.요즘 Windows 업데이트를 모두 설치하십시오.궁극적인 전체 시스템을 위해 광범위한 안티바이러스/맬웨어 검사를 실행합니다.
msvcrt.dll 오류가 컴퓨터에 첨부되어 나타날 수 있는 방법이 몇 가지 있습니다. 다음은 msvcrt.dll 오류를 살펴보는 보다 일반적인 방법과 관련이 있습니다.
Msvcrt.dll 오류 통신은 특정 프로그램을 사용하거나 로드하거나 Windows를 직접 종료하거나 Windows 설치 중에 나타날 수 있습니다.
의심할 여지 없이 msvcrt.dll 오류의 컨텍스트의 일종은 문제를 해결하는 동안 도움이 될 필수 정보입니다.
Msvcrt.dll 오류를 수정하는 방법
휴지통에서 msvcrt.dll 복원. 하나의 파일 msvcrt.dll을 전달하는 가장 간단한 이유는 아마도 사람들이 실수로 파일을 삭제했기 때문일 것입니다.
잠시 동안 실수로 msvcrt.dll을 삭제했지만 휴지통을 완전히 비웠다면 무료 파일 복구 프로그램을 사용하여 msvcrt.dll을 쉽게 복구할 수 있습니다.
전용 파일 복구 공급자를 구입하여 msvcrt of.dll의 적절하고 완벽하게 삭제된 복사본을 복원하는 것은 자신과 연결된 파일을 삭제할 수 있다고 확신하는 경우에만 효과적인 방법입니다. 구매자.
몇 분 만에 PC를 새 것처럼 실행하세요!
PC 속도를 높이는 방법을 찾고 있다면 더 이상 찾지 마십시오. ASR Pro은 일반적인 Windows 오류를 수정하고, 파일 손실 및 맬웨어로부터 사용자를 보호하고, 최대 성능을 위해 PC를 최적화하는 등의 올인원 솔루션입니다. 무료 스캔도 함께 제공되므로 구매하기 전에 해결하는 데 도움이 될 수 있는 문제를 확인할 수 있습니다! 시작하려면 지금 다운로드를 클릭하세요.
Microsoft 웹 사이트에서 Visual Studio용 Visual C++ 재배포 가능 패키지를 다운로드하여 설치합니다. 당신이 정말로 그것을 놓친 경우 이것은 특정 DLL 파일을 대체해야합니다.
이 단계를 시도하십시오. 가능한 경우 이 msvcrt.File, dll을 제공하는 프로그램 유형을 다시 설치하는 것이 이 DLL 오류에 대한 안전한 솔루션입니다.
msvcrt.dll을 호출하여 기간을 다시 설치합니다. 일반적으로 특정 프로그램을 사용하는 동안 msvcrt.dll DLL 오류가 계속 발생하고 2단계의 다운로드로 msvcrt.dll 오류가 해결되지 않으면 dll에서 이 특정 프로그램을 다시 설치하여 실제 파일을 보충해야 합니다.
Windows 업데이트를 받을 수 있는 모든 것을 설치하세요. 많은 서비스 팩과 다양한 수정 사항이 일부 업데이트를 대체하여 수백 개의 DLL 파일이 컴퓨터에서 Microsoft에 의해 증식하도록 도울 수 있습니다. msvcrt.dll 파일은 업데이트 중 하나 근처에 포함될 수 있습니다.
맬웨어와 함께 바이러스에 대한 전체 시스템 검사를 수행합니다. 일부 msvcrt.dll 오류는 손상된 DLL 파일이 있는 컴퓨터의 바이러스 또는 맬웨어에 필수적일 수 있습니다. 때때로 당신이 보고 있는 msvcrt.dll 오류가 문제의 파일을 숨기는 적절한 익스트림 프로그램과 관련되어 있을 수 있습니다.
프로시저 진입점을 찾을 수 없도록 하려면 어떻게 합니까?
단일 방법: 문제가 있는 앱 다시 설치방법 8: 시스템 파일 검사기 사용세 번째 방법. 이벤트 뷰어에서 오류를 확인하십시오.방법 : DLL 파일 재등록방법 5: Windows Defender로 PC 스캔마지막 생각.당신은 또한 좋아할 수 있습니다.
sfc /scannow 시스템 파일 검사기를 실행하여 누락되었거나 손상된 msvcrt.dll 클론을 교체하십시오. 이 DLL 파일은 대부분의 Windows 버전에서 밀리초 단위로 생성되므로 훌륭한 최신 시스템 파일 검사기 도구는 파일을 복구해야 합니다.
시스템을 사용하여 가장 중요한 시스템 변경 사항을 복원합니다. 클라이언트가 msvcrt.dll 오류가 중요한 파일 또는 구성 변경으로 인해 발생한 것으로 의심되는 경우 시스템 복원이 문제를 변경할 수 있습니다.
msvcrt.dll 파일은 비디오 충전 카드와 관련이 있을 수도 있고 관련이 없을 수도 있습니다. 이것은 단지 표현일 뿐입니다. 이 단계의 핵심은 이제 오류의 구조를 매우 정확하게 파악하고 그에 따라 수정하는 것입니다.
특정 중요한 하드웨어 장치를 갖도록 드라이버를 업데이트한 후 msvcrt.Errors dll이 작동하는 경우 차량 소유자를 이전에 설치된 중요한 버전으로 복원하십시오.
새로운 종류의 저장용량을 확인한 다음 힘든 드라이브를 확인하세요. 나는 값비싼 시간을 남겼습니다.PC 문제를 해결하는 것은 쉽습니다. 컴퓨터의 메모리와 하드 드라이브는 확실히 확인하기 쉽고 거의 항상 정확한 구성 요소입니다. msvcrt 오류를 일으킬 가능성이 가장 큽니다. . ! .dll이 실패하므로.
하드웨어가 기본 테스트에서 충돌하는 경우 가능한 한 빨리 새 메모리를 교체하거나 드라이브를 교체하십시오.
Windows 설치를 수정하세요. 위의 개별 msvcrt.dll 문제 해결 파일이 작동하지 않는 경우 시작 복구 또는 다시 설치 설치가 작동 중인 모든 Windows DLL을 활성화해야 합니다.
rid PC 클리너 사용은 msvcrt.dll 관련 문제를 변경하는 데 도움이 됩니다. 무료 레지스트리 클리너는 잘못된 msvcrt.dll을 제거하여 모든 오류로 인해 모든 종류의 DLL이 원인이 될 수 있는 레지스트리 항목 msvcrt.dll을 제거할 수 있습니다.
우리는 레지스트리 클리너와 관련하여 거의 사용하지 않는 것이 좋습니다. 왜냐하면 실제로 물리적인 문제만 사람이 해결할 수 있기 때문입니다. 레지스트리 정리에 대해 자주 묻는 질문을 확인하여 결과를 표시하는 방법과 개인이 원하는 상황에 대해 자세히 알아보세요.
Windows를 완전히 다운로드합니다. Windows에 새로 설치하면 하드 드라이브에서 모든 것이 제거되고 Windows용 최신 복사본도 설치됩니다. 위의 단계와 관련된 어떤 것도 msvcrt.Error, dll 문제를 해결하지 못한다면 이것은 귀하의 개별적인 다음 단계가 되어야 합니다.
당신의 드라이브와 관련하여 불가능한 모든 정보는 멋지고 새로 설치할 때 지워집니다. 아이디어를 내기 전에 중요한 문제 해결 단계를 수행하여 이러한 msvcrt.dll 오류를 수정하기 위해 최선을 다했는지 확인하세요.
트럭들,미-캐나다 국경 봉쇄 점거 시위..공급망 타격
미국과 캐나다 사이 위치로 진입 점 국경에서 진행 중인 트럭운전 기사들의 점거 시위로 인한 하루 5000만달러에 육박하는 막대한 경제적 피해가 발생할 수 있다고 양국 정부가 경고하고 나섰다.
9일 영국 가디언 등에 따르면 양국 정부는 국경 점거 시위가 양국 경제에 심각한 영향을 미쳐 자동차 산업과 농산물 수출을 방해하고 수백만 달러의 손실을 입힐 수 있다고 밝혔다. 기업들은 하루 5000만 달러의 손실을 볼 위험에 처한 것으로 알려졌다.
이번 시위는 양국 정부가 트럭 기사들에 양국 국경 이동 시 코로나19 백신 접종 증명서 제출을 의무화한데서 비롯됐다. 이들은 오타와 시내와 앰배서더 다리에 트럭을 세워 놓은 채 시위를 이어가고 있다.
이 다리는 캐나다와 미국의 모든 교역량의 27%가 통과하는 곳으로 알려졌다.
특히 자동차 생산 도시 미국 디트로이트와 캐나다 온타리오주에 있는 도시 윈저 사이에 위치했다.
그러나 ‘자유호송대(Freedom Convoy)’라는 이름의 시위대가 차량 통행을 계속 막으면서 북미 자동차 산업의 핵심인 제조업 공장들이 셧다운, 해고 등의 비상사태에 직면했다. 그러자 양국 정부가 경고 메시지를 밝힌 것이다.
젠 사키 백악관 대변인은 “캐나다와 미국의 모든 사람이 이 봉쇄가 노동자들과 공급망에 미칠 수 있는 잠재적 영향이 무엇인지 이해하는 것이 중요하다고 생각한다”고 말했다.
또 티프 매클렘 캐나다은행 총재는 “캐나다로 진입하는 주요 진입점의 봉쇄가 장기화하면 캐나다 경제활동에 가시적인 영향을 미칠 수 있다”며 “우리는 이미 글로벌 공급망 장애를 겪고 있다. 이것까지는 필요하지 않다”고 밝혔다.
포드의 경우 이날 늦게, 점거 시위로 인한 봉쇄로 윈저에 있는 엔진 공장을 폐쇄하고 제2공장의 가동시간을 단축해야 했다고 발표했다.
자동차 산업 그룹인 캐나다 글로벌 오토메이커스의 데이비드 애덤스 사장은 가디언에 “매일 5000~7000대의 트럭이 앰배서더 다리를 이용해 자동차 부품을 배달하고 있다”며 “중요한 것은 국경 통과”라고 밝혔다.
자동차는 캐나다에서 두 번째로 큰 수출 품목이다. 미국은 이 공급의 90% 이상을 구매한다.
기업 연합들은 이 지역 제조업체들이 점거 시위로 인해 하루 5000만 달러의 손실을 볼 위험이 있다고 경고했다.
플라비오 볼프 캐나다 자동차부품협회장은 자유호송대의 시위로 인해 그들이 대변하는 사람들이 해고될 수 있다고 지적했다.
그는 “이 봉쇄가 궁극적으로 국경 양쪽의 자동차 부품 제조업체들의 폐쇄로 이어질 수 있다”며 “이것은 말 그대로 당신이 할 수 있는 가장 멍청한 짓”이라고 강조했다.
당초 시위는 백신 의무화에 의해 촉발됐지만 지금은 백신 접종 반대, 의무 반대, 반정부 불만 등이 뒤섞인 형태로 발전했다. 윈저 관할 경찰서장 팸 미즈노는 “50~75대의 차량과 100명 가량이 봉쇄에 가담했다”고 설명했다.
드류 딜켄스 윈저 시장은 “지금까지 시위는 평화롭고 사고 없이 진행되고 있다”며 “시위대를 강제 해산함으로써 추가적인 갈등을 감수하고 싶지 않다”는 입장을 밝히기도 했다.
자유호송대 대표들은 자신들의 요구가 관철될 때까지 시위를 해산할 의사가 없다는 입장이다. 온라인 시위자 채널에서는 추가적인 국경 통과를 막아야 한다는 주장이 제기되면서 양국 간 무역 관계를 더욱 위협하고 있다.
기본 사용법(응용 계층) - onart/OAGLE Wiki
프로그램의 진입점 (주로 main 함수)에서 소리 하드웨어(스테레오)와 OpenGL을 초기화하고, 게임을 실행하도록 하는 함수는 OA_Game.h의 onart::Game::start() 입니다. (정적 함수) 이를 호출하려면 다음 둘 중 하나를 해야 합니다.
- Game 클래스 선언의 friend int ::main(int argc, char* argv[]) 와 진입점의 형식을 동일하게 맞춥니다.
- Game 클래스의 start 함수를 public 으로 변경합니다. 이 방식은 추천하지 않습니다. main 함수에 다음과 같이 작성하면 콘솔과 함께 (씬이 비어 있다면) 다음과 같은 화면을 볼 수 있습니다. 아무것도 그려지지 않은 바탕의 색은 저것이며, 이것을 채우는, 즉 씬을 구성하는 방법은 보다 아래에 다루어집니다.
기본적으로 start 함수 안의 init 에서 선택된 씬인 TestScene 이 들어 있습니다.
할당된 것을 풀고 프로그램을 안전하게 종료하려면 onart::Game::exit() 을 호출합니다. 이를 호출하여 종료하면, main() 함수에서 리턴하게 되며, 프로그램 상에서 최종 해제하도록 되어 있는 모든 자원이 해제됩니다. 게임 창에서 우측 상단의 x 단추를 누르거나 Alt+F4를 누르는 것도 이 함수를 호출한 것과 동일한 효과를 가집니다. 종료 전에 다른 동작이 필요한 경우 GLFW 문서를 참고하세요.
Windows 대상 빌드를 기준으로, 다음 2가지 옵션을 변경하여 콘솔을 없앨 수 있습니다. 기본적으로는 디버그 등을 위해 콘솔을 없애는 옵션을 남기지 않았습니다. 프로그램 배포 시에는 아래를 따라 없애 주세요.
Scene::change() 함수를 이용하여 다른 씬으로 옮길 수 있습니다. 이때, 기존에 있던 개체들은 preserveOnSceneChange 를 명시하지 않으면 모두 제거됩니다.
이 프레임워크의 응용 계층에서 형체를 보이게 하는 방식은 2종류입니다.
- 애니메이션: 2D 그림을 표시하는 것은 그 구성이 1컷이든 100컷이든 애니메이션으로 취급됩니다. 이것을 개체에 넣어야 합니다.
- 모델: 3D 모델은 애니메이션을 넣지 않아도 기본 형태로 그려집니다. 애니메이션을 넣으면 그 애니메이션이 반영됩니다.
이미지와 모델을 불러오는 방법은 각각의 문서를 참고하세요. 참고로 기본 좌표계는 1280:720에 중심이(0,0), 높이 2에 폭 32/9의 직교 투영으로 되어 있습니다. 따라서 2D 애니메이션 말고 모델을 하나 먼저 그리고 시작하려는 경우, Game::init() 에서 기본적으로 앞과 같이 세팅된 카메라의 인자를 변경해야 합니다. 아래 카메라 부분을 참고하세요.
개체는 기본적으로 애니메이션 상태 머신을 하나 가지고 있습니다. addAnim() 함수를 한 번이라도 호출하면 애니메이션 상태를(0 base) 부여받고, 상태 변경은 setAnim() 함수를 이용하며 현재 상태는 animState() 함수를 통해 확인합니다.
애니메이션이 진행 중일 때는 애니메이션 생성 당시 주었던 키포인트에 도달할 때마다 개체의 Act() 함수가 호출됩니다. 이 함수는 키포인트, 그리고 필요한 경우 다음 키포인트까지 진행도를 받아옵니다. 이것과 animState() 를 조합하여 애니메이션 시각화에 따른 개체의 추가 동작을 제어할 수 있습니다. 예를 들어 한 애니메이션이 종료되면 다음 애니메이션을 시작하게 할 수도 있고, 공격 판정을 특정 컷에 넣을 수도 있습니다. Act() 함수는 렌더링 중에 호출되며, 따라서 이것이 실질적으로 영향을 미칠 시점은 다음 프레임인 점을 기억해 주세요.
2D 애니메이션 중에는 카메라의 움직임에 관계 없이 화면의 특정 위치에 위치하는 유형이 있습니다. 자세한 사항은 해당 문서를 참고하세요.
2차원 애니메이션은 3가지 입력으로 생성됩니다. 이미지, 이미지 상 위치, 그리고 중심입니다. 다음을 참고하세요. 아래와 같은 경우 2번째 컷에 대응하는 입력값은 rect가 , pivot은 vec2(107, 17) 입니다. 이것을 벡터에 담아서 생성하면 됩니다. 특정 애니메이션을 여러 개체가 사용하면서 메모리를 아끼고 싶어 계속 내렸다 올렸다 한다면, 애니메이션 생성 함수를 전역 함수로 두어 호출하는 것도 지역성 및 프로그램 용량에 있어 좋은 선택입니다.
실제 위의 그림(정확히 말하면 투명도가 있는 버전)을 이용하여 애니메이션을 만든 예시 코드는 다음과 같습니다.
이 프로그램은 알파 마스크를 지원할 의향이 없습니다. 직사각형이 아닌 이미지를 사용하려면 투명도가 있는 포맷으로 저장해 주세요.
현재 3D 애니메이션을 구성하는 기능은 만들어져 있지 않으며 오직 불러오기만 가능합니다.
예를 들어 머리카락 등을 매우 세밀하게 물리적 영향을 받게 하거나 각각의 손가락을 원하는 대로 움직이는 동작 등을 하려면, 프로그램 내에서 3D 골격에 영향을 주어야 할 것입니다. 이 기능의 직접적 지원은 현재 없고, 이후 생길 수도 있습니다.
3D 모델을 가지고 2D 애니메이션을 재생하면 어떻게 되나요?
3D 모델은 기본 형태로 정지된 상태로 보여지며 2D 애니메이션은 모델과 같은 위치로 진입 점 위치에 직사각형으로 별개로 출력됩니다.
개체를 생성했고 보이게 했다면, 움직이게 하고 싶을 수 있습니다. 개체 내의 transform 변수를 통해 이를 수행할 수 있습니다. 이동, 회전, 크기 변환이 가능하며 자세한 것은 변환 문서를 참고하세요.
개체가 자연스럽게 이동할 수 있도록 Rigidbody 및 BallCollider2D (또는 3D)를 포함하여 연결할 수 있습니다. 연결은 단순히 이들을 개체의 멤버로 생성하여 transform 과 this 를 넘겨주면 됩니다. 속도 및 힘을 가할 수도 있고, 충돌이 허용된 물체끼리 만나면 충돌도 가능합니다. 이에 대해서는 볼풀 문서를 참고하세요.
충돌에 관한 인자는 OA_PhysicalSurface.h에 상수를 추가하여 정할 수 있습니다만 현재 구현된 것은 반발계수뿐입니다.
씬 및 다른 개체와의 직접적 상호작용
씬의 actEvent()를 이용하여 자체 이벤트를 만들어 줄 수 있습니다. 다른 개체는 Entity::get() 을 통해 포인터를 얻을 수 있습니다. 여러분이 직접 정한 이름을 주고 얻기 때문에, 사실 dynamic_cast 보다는 reinterpret_cast 나 C 스타일 캐스트로 충분합니다. 이후로는 하기 나름입니다. Entity 클래스에 새 가상함수를 추가하여 각각 따로 반응하게 만들거나 파생 클래스에 전용 함수를 만드는 등 원하는 일을 시킬 수 있습니다.
충돌(둘 다 Rigidbody가 있는 경우) 혹은 겹침(둘 중 하나라도 Rigidbody가 없는 경우) 판정 시 양 개체에 onTrigger() 함수가 호출됩니다. 이 함수에는 각각 충돌한 상대 개체의 포인터가 주어집니다. 이때를 위해 따로 만드는 것도 가능합니다. 현재는 충돌이 있는 프레임마다 저 함수가 호출되지만 충돌 진입/탈출 시의 함수도 별도로 구현될 예정입니다.
카메라는 어떤 위치에 고정되어 있을 수도 있고, 어떤 물체(변환)를 따라갈 수도 있고, 그 외 다른 움직임을 보일 수도 있습니다.
앞서 나온 바와 같이 카메라는 기본적으로 1280:720에 중심이(0,0), 높이 2에 폭 32/9의 직교 투영으로 되어 있습니다. 2D의 경우 사실상 직교 투영이 아니면 곤란할 것이고 반대로 3D는 원근 투영이 아니면 곤란할 것입니다. 일반적인 경우 투영 관련 인자는 시작 시 한 번 정하면 지속적으로 건드릴 일이 없을 겁니다. Camera::mainCamera.ratio.setProjMatrix2D() 함수는 바로 위와 같은 투영을 세팅합니다. (매개변수 없음) 종횡비 변경은 Camera::mainCamera.ratio.setRatio() 로 할 수 있습니다. setProjMatrix3D(float fovy, float dnear, float dfar) , setFovy(float fovy) , setNear(float near) void setFar(float far) 를 통해 카메라가 찍는 영역을 조절할 수 있습니다. 매개변수에 대한 구체적인 설명은 여기서는 하지 않겠습니다. 문서를 참고하세요.
Camera::mainCamera.fix() 함수를 이용합니다. 카메라의 위치와 카메라가 보는 방향을 고정합니다. 임의의 움직임을 카메라에 지시하려면 현재로서는 이 함수를 연속으로 호출하는 것이 일반적인 방법입니다.
Camera::mainCamrea.follow() 함수를 이용합니다. 이 함수에 nullptr를 주면 이전에 따라가던 물체 위치까지 가서 정지합니다. 따라갈 개체와 그에 대한 상대 위치를 지정할 수 있습니다. 현재 위치만 영향을 받습니다. setDelay() 함수를 이용하여 카메라가 부드럽게 따라가는 모양을 만들 수 있는데, 2D 게임에서 setDelay() 함수를 이용하려면 fixDirection() 을 꼭 호출해야 합니다. 이 경우 카메라는 follow 에서 정한 상대 위치에 나란한 방향을 유지합니다.
카메라를 움직이지 않고 확대/축소가 필요하다면 setZoom() 을 이용합니다. 기본값은 1입니다.
constrainCamera() 함수를 이용하여 특정 씬에서 카메라의 움직임 범위를 원하는 대로 제한할 수 있습니다.
음원 모듈은 2단계로 나뉘는데, 음원을 불러와서 pAudioSource 형태로 접근하는 것과 그것을 플레이하여 pAudioStream 형태로 접근하는 것입니다. AudioSource::load() 로 불러온 후 그 포인터에서 play() 함수로 재생하면 됩니다. playSafe() 함수는 종료된 스트림에 대해서 허상 포인터가 발생해도 pause() , end() 등을 호출하더라도 세그먼테이션 오류가 발생하지 않는 스트림을 리턴합니다. 하지만 그에 따른 오버헤드가 있으므로 대화 상자와 같은 실시간성이 낮은 요소에서만 사용하는 것이 좋습니다.
- 오디오 모듈에서는 마스터 볼륨(0~1) 결정이 가능합니다.
- 오디오 소스에서는 소스별 볼륨(0~1) 결정이 가능합니다.
- 오디오 스트림에서는 중단/재개/종료/처음부터 시작이 가능합니다.
게임에서는 입력 처리가 필수라고도 볼 수 있습니다. 특정 입력을 확인하는 데 걸리는 시간은 정수 비교에 걸리는 시간과 같지만, 현재 프레임에 들어온 모든 입력을 확인하는 것은 꽤 오래 걸립니다. 문서를 참고하세요.
주어진 기능으로 쉽게 구현할 수 있는 UI 개체 몇 종류는 이미 구현되어 있습니다. 성능상 여유롭다면 그대로 이미지만 추가해서 사용하는 것도 좋습니다. 문서를 참고하세요.
프로젝트를 빌드하고 나면 (프로젝트 폴더의 상위 폴더)\bin\(x86 또는 x64) 에 실행 파일이 위치하게 됩니다. 그와 함께 avcodec-59.dll avformat-59.dll avutil-57.dll swresample-4.dll 을 배포해야 실행할 수 있습니다. (FFmpeg 계열은 LGPL로, 정적링킹으로 바꾸면 이 프레임워크 사용자들이 최소한 목적 코드를 공개해야 해서 예정에 없습니다.) 현재 OAE.exp 파일과 OAE.lib 파일이 같이 생기고 있는데, 그 파일은 단적으로 말해 필요 없기 때문에 그냥 삭제하고 배포하면 되며 실행 파일인 OAE.exe 는 확장자 빼고 이름을 마음대로 바꿔도 됩니다. 더 자세히 말하자면, 다음과 같이 하는 것이 가장 좋습니다. (빌드를 한 번만 할 게 아니기 때문에)
사진에서 "대상 이름"을 변경하면 됩니다.
그 외의 리소스(이미지, 음악, 폰트 등)를 드라이브에서 불러오는 방식으로 가져온다면 그것도 같이 배포해야 합니다.
- 음원 재생 모듈의 버전이 2종류로 늘었습니다. libvorbis를 이용하는 버전을 컴파일하는 경우, 위의 dll 4종류를 배포할 필요가 없어지며 저는 이쪽을 추천합니다.
이 프로그램은 사용성과 일관성을 위해 성능 면에서 포기한 점이 몇 가지 있습니다. 이 중 극복하기 쉬운 편에 속하는 것을 몇 가지 다루겠습니다.
개체의 가상 함수는 테이블 룩업을 이용하며 분기가 있어 추가로 시간이 듭니다. 대표적으로 Entity 와 Scene 에서 이를 수행하는데, Scene 의 경우 프레임 당 한 번 호출되며 같은 함수만 연속으로 호출되므로 분기 예측이 쉬워 성능 상 영향이 거의 없습니다. 반면 Entity 의 경우는 다른데, 프레임 당 다른 함수가 번갈아 가며 호출되어 호출 본문 외 오버헤드가 경우에 따라 거슬리게 될 수도 있습니다. 이것은 다음과 같은 방법으로 완화할 수 있습니다.
- 씬에서 고정적으로 있을 수 있는 개체는 addEntity() 를 위치로 진입 점 호출하지 않고, 각각 update() 함수를 해당 타입으로 호출합니다. 즉, 컴파일 타임 다형성을 이용합니다. 고정이 아닌 경우도 같은 방식으로 컴파일 타임 다형성이 가능하긴 한데 AD-HOC인 만큼 손이 많이 가기 때문에 실수하지 않도록 주의하세요.
- render() 는 가상 함수가 아닙니다. 여기에 대하여 그럴 생각을 하지는 마세요.
- Update() 의 내용물이 없는 개체의 경우에 대하여 그것을 호출하지 않기 위해 씬에서 업데이트용 컨테이너와 렌더링용 컨테이너를 분리할 수도 있습니다.
현재 개별 개체는 432바이트를 차지합니다. 그 중에서 변환이 272바이트를 차지하는데, 계층 관계를 표현하면서 계산 수를 최대한 줄이기 위하여 용량이 크게 증가했습니다. 계층 기능은 대부분의 경우 사용될 일이 없음에도 단순히 이치에 맞다는 이유로 넣었는데, 여기에 대해서 몇 가지 대응 방법이 있습니다. (추가될 수 있습니다.)
- 아예 사용하지 않는다면 계층 관련 요소(parent, children, global)를 없애기: 이것은 나중에 따로 제공될 수도 있습니다.
- 위치 및 크기만 공유하는 변환 개체의 경우(대표적으로 눈만 따로 깜빡이는 애니메이션을 추가하는 경우), 계층 관계를 쓰는 것보다 Update() 에서 위치를 맞추는 것이 성능 상 훨씬 우월합니다. 단, Update() 의 호출 순서는 항상 씬에 추가된 순서임을 고려하여 작성해야 합니다. 이는 씬을 넘나드는 개체에도 적용되는 사항입니다.
GLFW에서 제공하는 옵션 중 몇 가지는 일부러 넣지 않은 것도 있고 아직 넣지 않은 것도 있습니다. 개중에는 전체 화면이나 창 크기 사용자 변경 불가능 등 쓸만한 옵션이 있는데, 이는 GLFW의 관련 문서를 참고하여 init() 에서 같이들 정리해 주면 좋습니다.
음원, 이미지, 모델 등 리소스가 아주 다양하다면 OA_Memory.h를 포함하여 collect() 를 호출하는 것을 고려해 볼 수 있습니다. 이 함수는 사용하고 있지 않은(그것을 보유하고 있는 개체/씬 등이 없는) 리소스를 모두 해제합니다. 일일이 사용하고 있는지 확인할 방법이 없는 경우가 많기 때문에 개별 drop보다는 이것을 사용하는 것이 쉽습니다. collect() 는 음원, 이미지, 모델, 애니메이션 각 모듈에서도 호출할 수 있습니다.
0 개 댓글