Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

99% CPU, 3.51MB without typedef

Tags:

c++

c++11

Ok so I have roughly 500 function pointers defined in a header like so for example:

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);

Etc.. Now the reason I did not put the typedef or did not want to was because I can assign to and use the pointers above directly. However, if I use the typedef, then I need to create a variable of said type and assign to it then use it. That just doubles my code from 500 lines to 1000+.

Now when I add a typedef at the beginning of each of those function pointers, my dll is 300kb and compiles in less than 5 seconds.. However, if I remove the typedef as show above, it skyrockets to 99% cpu when compiling and outputs a 3.51MB dll all while taking 3-4 minutes to compile.. Its outrageous that one keyword causes so much trouble.

Within the DLL's def file, it shows:

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

But with the typedef, that "DATA" part is gone.

Any ideas what makes the typedef so special and why this behaviour without it :S? I'm using Mingw G++ 4.7.2 with Codeblocks Windows-7 x64 3.7Ghz I7 8Gb Ram with the compiler output being:

-------------- 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: Entire DLL (containing only 1/500 func pointers as requested):

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;
}
like image 424
Brandon Avatar asked Jun 02 '13 14:06

Brandon


1 Answers

With typedef your header is producing a lot of new types, each being a function pointer type. Types are useful for compilation process only and produce no trace in the DLL itself. typedef does not produce any global variables.

However, without typedef your header is producing a series of global variables, each being a function pointer. Global variables do take an entry in the DLL, increasing the file production time and its final size.

like image 57
CygnusX1 Avatar answered Oct 24 '22 06:10

CygnusX1