IT

c++ 주 기능에서 다른 기능으로 변경하려면 어떻게 해야 합니까?

itgroup 2023. 10. 10. 20:13
반응형

c++ 주 기능에서 다른 기능으로 변경하려면 어떻게 해야 합니까?

C++ 에서 C.main()다른 어떤 기능에도 적용할 수 있습니다.그게 어떻게 가능해?

표준 C(그리고 C++도 마찬가지로)에서는 적어도 호스트 환경의 경우에는 불가능합니다(아래 참조).C은 C합니다.main 표준(c99)은 논쟁의 여지를 많이 남기지 않습니다.

5.1.2.2.1 프로그램 시작: (1) 프로그램 시작 시 호출되는 기능을 main이라고 합니다.

바로 그겁니다.그런 다음 매개 변수와 반환 값에 대해 약간 설명하지만 이름을 변경할 여지가 없습니다.

이는 호스트 환경을 위한 것입니다.이 표준은 또한 독립적인 환경(즉, 임베디드 시스템과 같은 경우에는 OS가 없음)을 허용합니다.자유롭게 서 있는 환경의 경우:

(운영 체제의 이점 없이 C 프로그램 실행이 이루어질 수 있는) 자유로운 스탠딩 환경에서는 프로그램 시작 시 호출되는 함수의 이름과 유형이 구현 정의됩니다.제4항에 의해 요구되는 최소 세트를 제외하고, 독립형 프로그램이 이용할 수 있는 모든 라이브러리 시설은 구현 정의됩니다.

C 구현에서 "꼼수"를 사용하면 다음과 같이 보일 수 있습니다.main진입점이 아닙니다. 초기 기 Windows입니다를 한입니다.WinMain


번째 는 : 와 에 주 전 할 수 .start.o이 코드 은 C 하고 C됩니다를 되는 것입니다.main 것으로 대체하는 것을 .bob대신.


두 번째 방법: 일부 링커는 시작 코드를 다시 컴파일하지 않고 변경할 수 있도록 명령줄 스위치와 함께 이 옵션을 제공합니다.


세 번째 방법: 이 코드 조각과 연결할 수 있습니다.

int main (int c, char *v[]) { return bob (c, v); }

코드를 입력하는 시점은bobmain.


하지만, 이 모든 것들은, 아마도 학문적인 관심이 있기는 하지만, 이것이 필요하거나 바람직한 수십 년 동안의 암호를 끊는 데 있어서 단 하나의 단독 상황도 생각할 수 없다는 사실을 바꾸지는 못합니다.

저는 인터뷰 진행자에게 묻고 싶습니다: 왜 이런 일을 하고 싶으십니까?

입니다._start기능(crt1.o에 implement되어 있음)

_start합니다를 합니다.main(int argc,char* argv[], char* env[])할 수 ._start.mystart링커 파라미터를 설정함으로써:

g++ file.o -Wl,-emystart -o runme

입니다를 _start다를(를) 수 .

void mystart(){

}

생성자 또는 소멸자가 있는 전역/정적 변수는 응용 프로그램을 시작할 때 초기화하고 마지막에 제거해야 합니다.자동으로 수행되는 기본 진입점을 우회할 계획이라면 이 점에 유의해야 합니다.

C++ 표준 문서 3.6.1기능에서,

프로그램에는 프로그램의 지정된 시작인 메인(main)이라는 글로벌 기능이 포함되어야 합니다.주 기능을 정의하기 위해 독립된 환경의 프로그램이 필요한지 여부는 구현이 정의됩니다.

그럼, 당신의 컴파일러/링커에 따라 다르겠죠...

VS2010을 사용하고 계신다면, 이를 통해 몇 가지 아이디어를 얻을 수 있을 것입니다.

이해하기 쉽기 때문에, 이는 C++ 표준에 의해 의무화된 것이 아니며 '구현 특정 행위'의 영역에 속합니다.

이는 추측성이 강하지만 메인이 아닌 정적 이니셜라이저를 사용할 수도 있습니다.

#include <iostream>

int mymain()
{
    std::cout << "mymain";
    exit(0);
}

static int sRetVal = mymain();

int main()
{
    std::cout << "never get here";
}

시공자에 물건을 넣어 '자바처럼' 만들 수도 있습니다.

#include <iostream>

class MyApplication
{
public:
    MyApplication()
    {
        std::cout << "mymain";
        exit(0);
    }
};

static MyApplication sMyApplication;

int main()
{
    std::cout << "never get here";
}

지금은 면접관이 생각했을 수도 있지만 저는 개인적으로 절대 사용하지 않을 겁니다.그 이유는 다음과 같습니다.

  • 관습적이지 않습니다.사람들은 그것을 이해하지 못할 것입니다, 진입 지점을 찾는 것은 사소한 일이 아닙니다.
  • 정적 초기화 순서는 비결정적입니다.다른 정적 변수를 넣으면 초기화가 되면 지금은 절대로 할 수 없습니다.

하지만, .init()라이브러리 초기화자의 경우.주의할 점은 (경험상) DLL의 정적이 사용량에 따라 초기화되거나 초기화되지 않을 수 있다는 것입니다.

하는 crt 합니다를 합니다.main()기능, 또는 사용자 고유의 기능을 제공합니다(일반 링크를 비활성화하는 것을 잊지 마십시오).

gcc의 경우, 속성((contributor))을 가진 함수를 선언하면 gcc는 main을 포함한 다른 코드보다 먼저 이 함수를 실행합니다.

Solaris Based Systems의 경우 를 찾았습니다.사용할 수 있습니다..init모든 플랫폼에 대한 섹션:

   pragma init (function [, function]...)

출처:

이 프래그마를 사용하면 .init 섹션에 호출을 추가하여 나열된 각 함수가 초기화 중(메인 이전) 또는 공유 모듈 로드 중에 호출됩니다.

매우 간단합니다.

c에서 상수를 사용할 때 알고 있듯이 컴파일러는 각각의 값에 대해 상수의 이름을 변경하는 일종의 '매크로'를 실행합니다.

합니다에 만 하면 됩니다.#define의 맨 름라는 .main:

예:

#define my_start-up_function (main)

링크하기 전에 객체에서 원하지 않는 메인() 기호를 제거하는 것이 쉬운 것 같습니다.

안타깝게도 g++에 대한 진입점 옵션이 작동하지 않습니다(진입점에 진입하기 전에 바이너리가 충돌함).그래서 객체 파일에서 원하지 않는 진입점을 제거합니다.

진입점 함수를 포함하는 두 개의 출처가 있다고 가정합니다.

  1. target.c에는 우리가 원하지 않는 주요 ()가 포함되어 있습니다.
  2. our_code.c에는 진입점이 되고자 하는 테스트 메인 ()가 포함되어 있습니다.

(g++ -c option) 컴파일 후 다음과 같은 객체 파일을 얻을 수 있습니다.

  1. 우리가 원하지 않는 주요 ()를 포함하는 target.o.
  2. 우리가 진입점이 되고자 하는 테스트 메인 ()를 포함하는 our_code.o.

따라서 목적어를 사용하여 원하지 않는 주() 함수를 제거할 수 있습니다.

objcopy --strip- symbol= main target.o

objcopy를 사용하여 test main()을 main()으로 재정의할 수도 있습니다.

objcopy --redefine-sym testmain=main our_code.o

그리고 나서 둘 다 이진법으로 연결할 수 있습니다.

g++ target.o our_code.o -o our_binary.bin

저는 이 정도면 돼요.가 달릴 때.our_binary.binour_code.o:main()다를 .our_code.c::testmain()기능.

또 다른 가 .TLS. 자세한 설명은 이 항목을 참조하십시오. http://isc.sans.edu/diary.html?storyid=6655

네, 메인 기능 이름은 예를 들어 다른 이름으로 변경할 수 있습니다.시작, 보브, 레미 등등.

컴파일러는 전체 코드에서 메인()을 검색해야 한다는 것을 어떻게 알 수 있습니까?

프로그래밍에서 자동적인 것은 없습니다. 누군가가 우리에게 자동적으로 보이게 하기 위해 어떤 일을 했습니다.

그래서 컴파일러가 메인을 검색해야 하는 것이 시작 파일에서 정의되었습니다.

이름을 메인으로 다른 것으로 바꿀 수 있습니다.Bob과 컴파일러는 Bob()만을 검색하게 됩니다.

Linker Settings에서 값을 변경하면 진입 지점이 재정의됩니다. 즉, MFC 응용 프로그램은 'Windows(/SUBsystem:WINDS)' 앱에서 진입점을 메인()에서 CW로 변경하려면:윈메인().

Right clicking on solution > Properties > Linker > System > Subsystem > Windows (/SUBSYSTEM:WINDOWS)

...

진입점을 수정할 때 매우 실용적인 이점:

MFC는 C++에서 윈도우즈 애플리케이션을 작성하는 데 활용되는 프레임워크입니다.오래된 일이라는 건 알지만, 우리 회사는 유산 때문에 하나를 유지하고 있어요!MFC 코드에서 메인()을 찾을 수 없습니다.MSDN에서는 진입 지점이 윈메인()이라고 합니다.따라서 기본 CW inApp 개체의 WinMain()을 재정의할 수 있습니다.또는 대부분의 사용자가 다음 앱에서 CW를 재정의합니다.기본 WinMain()이 호출하기 때문에 InitInstance().

면책 사항:저는 빈 괄호를 사용하여 방법을 나타내지만, 논쟁의 수는 신경 쓰지 않습니다.

언급URL : https://stackoverflow.com/questions/3974796/in-c-main-function-is-the-entry-point-to-program-how-i-can-change-it-to-an-oth

반응형