2013-06-02 6 views
15

なし3.51メガバイトので、私は、例えばそのようなヘッダで定義されたおよそ500関数ポインタを持っている:99%のCPU、[OK]をtypedefの

void (__stdcall *ptr_glAccum) (GLenum op, GLfloat value); 
void (__stdcall *ptr_glActiveTextureARB) (GLenum texture); 
void (__stdcall *ptr_glAlphaFunc) (GLenum func, GLclampf ref); 
GLboolean (__stdcall *ptr_glAreTexturesResident) (GLsizei n, const GLuint *textures, GLboolean *residences); 
void (__stdcall *ptr_glArrayElement) (GLint index); 
void (__stdcall *ptr_glBegin) (GLenum mode); 
void (__stdcall *ptr_glBindBufferARB) (GLenum target, GLuint buffer); 
void (__stdcall *ptr_glBindTexture) (GLenum target, GLuint texture); 
void (__stdcall *ptr_glBitmap) (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); 
void (__stdcall *ptr_glBlendFunc) (GLenum sfactor, GLenum dfactor); 
void (__stdcall *ptr_glBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); 

など。今、私はのtypedefを入れていないか、しませんでした理由は上記のポインタを直接割り当てることができます。しかし、もし私がtypedefを使用するならば、その型の変数を作成し、その型に割り当てる必要があります。それは私のコードを500行から1000+に倍増するだけです。

これらの関数ポインタの先頭にtypedefを追加すると、DLLは300kbで5秒未満でコンパイルされます。ただし、上記のようにtypedefを削除すると、99%のCPU 3.51MBのdllをコンパイルして出力すると、コンパイルするのに3〜4分かかります。その1つのキーワードが非常に問題を引き起こすのは馬鹿げています。

DLLのDEFファイル内では、それは示しています

ptr_wglUseFontBitmapsA @940 DATA 
ptr_wglUseFontBitmapsW @941 DATA 
ptr_wglUseFontOutlinesA @942 DATA 
ptr_wglUseFontOutlinesW @943 DATA 

しかし、typedefを持つ、 "DATA" の部分がなくなっていること。

何がtypedefを特別なものにするのでしょうか、それがないとこの動作がなぜ発生しますか?

-------------- Clean: Release in OpenGL32 (compiler: GNU GCC Compiler)--------------- 

Cleaned "OpenGL32 - Release" 

-------------- Build: Release in OpenGL32 (compiler: GNU GCC Compiler)--------------- 

x86_64-w64-mingw32-g++.exe -O2 -std=c++11 -Wall -DBUILD_DLL -std=c++11 -c C:\Users\Brandon\Desktop\OpenGL32\Implementations\Exports.cpp -o obj\Release\Implementations\Exports.o 
x86_64-w64-mingw32-g++.exe -O2 -std=c++11 -Wall -DBUILD_DLL -std=c++11 -c C:\Users\Brandon\Desktop\OpenGL32\main.cpp -o obj\Release\main.o 
x86_64-w64-mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libOpenGL32.def -Wl,--out-implib=bin\Release\libOpenGL32.a -Wl,--dll obj\Release\Implementations\Exports.o obj\Release\main.o -o bin\Release\OpenGL32.dll -s -static -static-libgcc -static-libstdc++ -luser32 -lgdi32 -lopengl32 -lglu32 
Output size is 3.51 MB 
Process terminated with status 0 (2 minutes, 39 seconds) 
0 errors, 0 warnings (2 minutes, 39 seconds) 

EDIT:(要求されたとしてのみ1/500 FUNCポインタを含む)全体のDLL:私は、コンパイラ出力された状態でコードブロックのWindows 7のx64 3.7Ghz I7 8GBのRAMを搭載したMingwをG ++ 4.7.2を使用しています

Exports.hpp:

#ifndef EXPORTS_HPP_INCLUDED 
#define EXPORTS_HPP_INCLUDED 

#include <GL/gl.h> 
#include <GL/glext.h> 
#include "Platform.hpp" 


extern Library* OriginalGL; 

void (__stdcall *ptr_glAccum) (GLenum op, GLfloat value); 

#endif // EXPORTS_HPP_INCLUDED 

Exports.cpp:

#include "Exports.hpp" 

Library* OriginalGL = nullptr; 

bool __stdcall Initialized(void) 
{ 
    char Root[MAX_PATH]; 
    #if defined _WIN32 || defined _WIN64 
     GetSystemDirectoryA(Root, MAX_PATH); 
    #ifdef _MSC_VER 
     strcat_s(Root, "\\opengl32.dll"); 
    #else 
     strcat(Root, "\\opengl32.dll"); 
    #endif 
    #else 
     strcat(Root, "/usr/lib"); 
     strcat(Root, "/libGL.so"); 
    #endif 

    OriginalGL = new Library(Root); 
    return OriginalGL->FunctionAddress(ptr_glAccum, "glAccum"); //Just a thin class wrapper around GetProcAddress and LoadLibrary. 
} 

bool __stdcall DeInitialize(void) 
{ 
    if (OriginalGL) 
    { 
     delete OriginalGL; 
     OriginalGL = nullptr; 
     return true; 
    } 
    return false; 
} 

extern "C" __stdcall void DetourHook_glAccum(GLenum op, GLfloat value) 
{ 
    (*ptr_glAccum) (op, value); 
} 

MAIN.CPP:

#include <windows.h> 

extern "C" bool __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 
{ 
    switch (fdwReason) 
    { 
     case DLL_PROCESS_ATTACH: 
      break; 

     case DLL_PROCESS_DETACH: 
      break; 

     default: 
      break; 
    } 
    return true; 
} 
+1

これは特定のコンパイラ固有のものですか?使用しているコンパイラとそのバージョンを指定すると便利です。 – misha

+0

「最初にtypedefを追加する」とはどういう意味ですか?あなたはあまりにもその例を見せていただけますか? –

+0

私はWindows x64 3.7Ghz I7 8GB RAMでCodeblocks IDEでMingwのg ++​​を使用しています。 :Sこれは次のような意味です: 'typedef void(__stdcall * ptr_glAccum)(GLenum op、GLfloat value);' – Brandon

答えて

17

typedefであなたのヘッダーは、各関数ポインタ型であること、新しいタイプの多くを生産しています。型はコンパイル処理にのみ役立ち、DLL自体にトレースを生成しません。 typedefではありません。はすべてのグローバル変数を生成します。

ただし、typedefがないと、ヘッダーは一連のグローバル変数を生成しており、それぞれが関数ポインタです。グローバル変数は、DLLのエントリを取って、ファイル生成時間と最終的なサイズを増やします。

+0

はい、typedefを使ってこれらのグローバル変数を作成する必要がありますが、どのような違いがありますか?S最新のOPサンプルをtypedefで表示しますか? – Brandon

+0

他の誰かが良いアイデアを持っていない限り、私はあなたの答えを受け入れるだろうと思っていますが、typedefの使用と大域の束の宣言と関数ポインタの直接使用の違いはありません。 Wikiはtypedefがエイリアスであること以外は何も言いません。 – Brandon

+0

私の答えに行を追加しました。 'typedef'はグローバル変数を生成しません!たぶん、タイプではなくグローバル変数が必要です。 – CygnusX1