2011-12-28 3 views
0

필자는 Windows 용 코드를 가지고 있으며, 지금은 리눅스로 포팅을 시도하고있다. 그러나 가능한지 확실하지 않다.exe ​​안에있는 함수를 어떻게 콜백합니까? (리눅스)

내 질문 : 공유 라이브러리에서 실행 파일에있는 함수에 콜백하려고합니다. 어떻게해야합니까?

저는 리눅스에서 매우 익숙한 편입니다. 제 질문이 너무 저평 많은 경우 저에게 알려주십시오. 내 실행 가능하도록 "ioq3ded.ppc64을"생각하는 이유, 즉

Output: 
    build/release-linux-ppc64/ioq3ded.ppc64 
    build/release-linux-ppc64/ioquake3.ppc64 
    build/release-linux-ppc64/baseq3/cgameppc64.so 
    build/release-linux-ppc64/baseq3/qagameppc64.so 
    build/release-linux-ppc64/baseq3/uippc64.so 
    build/release-linux-ppc64/missionpack/cgameppc64.so 
    build/release-linux-ppc64/missionpack/qagameppc64.so 
    build/release-linux-ppc64/missionpack/uippc64.so 

make[2]: Entering directory `/r/home7/XXX/ioquake3' 
make[2]: `build/release-linux-ppc64/ioq3ded.ppc64' is up to date. 
make[2]: `build/release-linux-ppc64/ioquake3.ppc64' is up to date. 
LD build/release-linux-ppc64/baseq3/cgameppc64.so 
LD build/release-linux-ppc64/baseq3/qagameppc64.so 
LD build/release-linux-ppc64/baseq3/uippc64.so 
LD build/release-linux-ppc64/missionpack/cgameppc64.so 
LD build/release-linux-ppc64/missionpack/qagameppc64.so 
LD build/release-linux-ppc64/missionpack/uippc64.so 

이것은 내가 내 프로그램을 실행하기 위해 실행하는 명령은 다음과 같습니다

은 컴파일 출력됩니다.
./ioq3ded.ppc64 +set fs_game Mod +set sv_pure 0 +set vm_game 0 +set vm_cgame 0 +set vm_ui 0 +set dedicated 1 +exec something_117.cfg 

Windows 용 코드입니다 :

//Called function 
__declspec(dllexport) void UnLinkLinkroutingcache(void) 
{ 
     //code 
} 

//Callback location 
#include<windows.h> 
typedef void (* fUnLinkLinkroutingcache_t)(void); 
void fUnLinkLinkroutingcache(fUnLinkLinkroutingcache_t pUnLinkLinkroutingcache) 
{ 
    pUnLinkLinkroutingcache(); return; 
} 
fUnLinkLinkroutingcache_t pUnLinkLinkroutingcache; 
void callUnlinkLink(void) 
{ 
    HMODULE hLib; 
    //fUnLinkLinkroutingcache_t pUnLinkLinkroutingcache; 

    hLib = LoadLibrary(TEXT("ioquake3.exe")); 
    if (hLib == NULL) 
     { 
     //Module not found, permission denied, ... 
     return 0; //inform caller of error 
     } 

    pUnLinkLinkroutingcache = (fUnLinkLinkroutingcache_t)GetProcAddress(hLib, TEXT("UnLinkLinkroutingcache")); 
    if (pUnLinkLinkroutingcache == NULL) 
    { 
     return 0; 
    } 

    fUnLinkLinkroutingcache(pUnLinkLinkroutingcache); 
} 

나는 포트에 리눅스 코드를 시도,하지만 난 EXE 파일을로드 할 수없는 것.

//Called function 
extern void UnLinkLinkroutingcache(void) 

//Callback location 
void callUnlinkLink(void) 
{ 
    void* handle; 
    void (*initializer)(void); 
    FILE *fp;//zgzg2020 

    fp = fopen("HereIsMe.txt", "a"); 
    if(fp != NULL) 
    { 
     fprintf(fp, "%d", 1); 
     fprintf(fp, "\n"); 
    } 
    fclose(fp); 

    handle = dlopen("./ioq3ded.ppc64", RTLD_LAZY); 
    if(handle == NULL) { 
     // report error ... 
     fp = fopen("ICantFindFile.txt", "a"); 
     if(fp != NULL) 
     { 
      fprintf(fp, "%d", 1); 
      fprintf(fp, "\n"); 
     } 
     fclose(fp); 
     exit(1);return; 
    } else { 
     initializer = dlsym(handle,"UnLinkLinkroutingcache"); 
     if(initializer == NULL) { 
      // report error ... 
      fp = fopen("ICantFindFfunction.txt", "a"); 
      if(fp != NULL) 
      { 
       fprintf(fp, "%d", 1); 
       fprintf(fp, "\n"); 
      } 
      fclose(fp); 
      exit(1);return; 
     } else { 
      // cast initializer to its proper type and use 
      (*initializer)(); 
     } 
     // use the result in a call to dlsym 
    } 
} 
+0

ioq3ded.ppc64는 라이브러리입니까? – dicaprio

+2

'dlerror'는 오류에 대한 자세한 정보를 제공합니다. 'fprintf (fp, "% d", 1);''fprintf (fp, "% s", dlerror());'를 시도하고 파일을 검사하십시오. 이미 duskwuff이 응답으로 언급했듯이,'dlopen'은 실행 파일에서 작동하지 않습니다. –

+0

나는 fprintf를 시도했다. (fp, "% s", dlerror()); Now :] 수신 된 신호 11, 종료 중 ... ----- Server Shutdown (신호 잡김) ----- – user598208

답변

1

할 수 있습니다 리눅스하지 dlopen 실행 - 기능은 (Windows의 .dll 거의 비슷 .so) 공유 라이브러리에서 작동합니다.

달성하려는 작업은 무엇입니까?

+0

삭제 해 주셔서 감사합니다. 외부에서 실행 파일 안에있는 함수를 호출하려고합니다. * .so 파일. 이도는 어때? – user598208

+0

외부 실행 파일 안의 함수에 대해서는 그렇게 할 수 없습니다 (별로 의미가 없기 때문에). –

0

dlopen() 함수는 null로 끝나는 문자열 filename에 의해 명명 된 동적 라이브러리 파일을로드하고 동적 라이브러리에 대해 불투명 한 "핸들"을 반환합니다. filename이 NULL이면 반환 된 핸들은 주 프로그램을위한 것입니다. 동적 라이브러리 여야한다는 것을 의미합니다.

+0

죄송합니다, 당신이 말하려고하는 것을 이해하지 못합니다 ... : ( – user598208

0

ioq3ded.ppc64가 .so (실제 모양이 아님) 인 경우 내 보낸 항목을 확인 했습니까?

dlopen에서 null 반환 값을 얻으면 errno를 확인 했습니까? (여기에 .so 파일이 있다고 가정하면 @duskwuff는 그 밖의 모든 것이 실패합니다)?

+0

제목에서 설명하려고했지만 외부에서 EXE 안에있는 함수를 호출하려고합니다. 어떤 아이디어입니까? – user598208

+1

바이너리 대신 공유 된 라이브러리에 넣으십시오. 다른 좋은 (좋은) 방법은 없습니다. 제목에 오타라고 가정했습니다. – Fredrik

+0

리눅스 라이브러리 작성에서 너무나 초라한 시도입니다. ><다른 제안 사항이 있습니까? – user598208

2

불행히도 dlopen은 다른 많은 포스터에서 말한 것처럼이 목적으로 충분하지 않습니다. 공유 라이브러리를로드 할 수 있습니다. 공유 라이브러리 경로 대신 NULL을 전달하면 런타임 링커가 주 실행 파일 이미지에서 제거하지 않은 심볼을 찾을 수 있습니다 (많지 않음).

-rdynamic없이 컴파일 된 실행 파일 내에서 함수를 호출하려면 /proc/self/exe을 통해 실행 파일의 실제 경로를 찾은 자신의 공유 라이브러리를 LD_PRELOAD 해보고 메모리 매핑 후 읽습니다. 기본 실행 파일 내에서 심볼을 찾아 해석하는 매핑 (또는 다른 실행 헤더)의 심볼 테이블.

공유 라이브러리에서 호출하려는 함수의 프로토 타입과 일치하는 몇 개의 함수 포인터를 정의하고, 심볼의 위치를 ​​바이너리에 할당 한 다음 함수 포인터를 다음과 같이 호출하는 것만 큼 표준.

+0

"-rdunamic"으로 다시 컴파일 한 다음 handle = dlopen (NULL, RTLD_LAZY); //하지만 계속 충돌합니다 ...><. "LD_PRELOAD"를 시도 할 수 있지만 "공유 라이브러리"는 실행 파일입니다. 먼저로드해야합니까 ?? – user598208

+0

"계속 유지 충돌 "은 설명하지 않는다. 문제는 나는 당신이 몇 가지 나쁜 가정을 가지고이 문제를 다루고 있다고 생각한다. 성취하려는 것을 더 잘 설명하여 질문을 업데이트해야합니다. – jmkeyes

관련 문제