Click to See Complete Forum and Search --> : my method to optimize application startup performance


George2
November 22nd, 2007, 02:39 AM
Hello everyone,


I found that for an application, if I specify the entry point function (e.g. main), the performance of startup will be greatly improved.

My questions are,

1. If no entry point is specified, how will debugger of Visual Studio find the entry point function? Will the time to search entry point function long?

For example, in my application, I defined the main function like this,

int main(void)

how will debugger treat main as the start point to execute (I set a break point to this function if I do not specify the entry point, then after a couple of minutes after pressing F5 to trigger debugger, debugger will jumps to main)?

If I specify the entry point to main, then debugger will directly jumps to this function after F5 debugging.

2. Specify entry point is a way to improve performance?


thanks in advance,
George

ovidiucucu
November 24th, 2007, 05:53 PM
2. Specify entry point is a way to improve performance?
NO, it isn't.
1. If no entry point is specified, how will debugger of Visual Studio find the entry point function?
Take a look in MSDN at /ENTRY (http://msdn2.microsoft.com/en-us/library/f9t8842e(VS.71).aspx) linker option.

George2
November 25th, 2007, 09:55 AM
Thanks ovidiucucu,


Good learning resource. I think if I bypass mainCRTStartup, I will miss some global environment initialization processes, right? What are the processes I missed and what are the potential impacts? Any further learning resources?

NO, it isn't.

Take a look in MSDN at /ENTRY (http://msdn2.microsoft.com/en-us/library/f9t8842e(VS.71).aspx) linker option.


have a good weekend,
George

JamesSchumacher
November 25th, 2007, 11:44 AM
Thanks ovidiucucu,


Good learning resource. I think if I bypass mainCRTStartup, I will miss some global environment initialization processes, right? What are the processes I missed and what are the potential impacts? Any further learning resources?




have a good weekend,
George

If you bypass mainCRTStartup or WinMainCRTStartup (depending on the application type) then you miss out on having global variables have 'auto initialization' and you cannot have static C++ objects. (No startup code to call constructors, and for that fact, with no runtime, do destructor calls either)

So pretty much you want to remove CRT dependence.

This is easy with a *.dll - not so easy with an application.

For a dll, make your entry point DllMainCRTStartup with the same signature as a regular DllMain, and 'link' against the Dll Runtime, then set the linker option to 'no default libraries'. Then you will have to add an *.lib files manually (windows libs for example, or other user *.dlls) that you want to use.

Just keep in mind that any global variables will not be initialized.

Also, understand without the C Runtime, you cannot use exception handling and other mechanisms that depend on the CRT. (__CxxThrowException)

If I remember correctly, without the C Runtime, new[] and delete[] become useless... If I remember correctly, it has something to do with the linker complaining about a missing 'scalar deleting destructor' reference.

In other words, if you use C++, new and delete are fine without the C Runtime (with Microsoft's compiler), but you will have to write a template function to simulate new[] and delete[]. This can be accomplished by prefixing a data buffer with a structure holding information about the array. Things like the number of objects, the size of each object (for debugging purposes), etc....

In this manner you will have to call constructors and destructors explicitly.


void * __stdcall AllocateMemory(unsigned long dwSize);
void __stdcall FreeMemory(void * lpBuf);

struct ArrayData
{
unsigned long ObjectSize;
unsigned long ObjectCount;
};

template <typename Type> Type * NewArray(unsigned long dwCount)
{
const unsigned long dwAllocSize = (dwCount * sizeof(Type)) + sizeof(ArrayData);

unsigned char * lpBuffer = reinterpret_cast<unsigned char *>(AllocateMemory(dwAllocSize));

if (lpBuffer != 0)
{
ArrayData * pPrefixData = reinterpret_cast<ArrayData *>(lpBuffer);

pPrefixData->ObjectSize = sizeof(Type);
pPrefixData->ObjectCount = dwCount;

ArrayData * pTemp = pPrefixData + 1;
Type * pTypeBuffer = reinterpret_cast<Type *>(pTemp);

Type * pStart = pTypeBuffer;
Type * pEnd = pTypeBuffer + dwCount;

while (pStart < pEnd)
{
pStart->Type(); // construct the object
++pStart;
}
}
}

template <typename Type> void DeleteArray(Type * pArray)
{
if (pArray != 0)
{
ArrayData * pData = reinterpret_cast<ArrayData *>(pArray);
pData = pData - 1;

const unsigned long dwCount = pData->ObjectCount;

Type * pEnd = pArray + dwCount;

while (pArray < pEnd)
{
pArray->~Type();
++pArray;
}

FreeMemory(pData);
}
}


The ironic thing is, I used this technique in the past, and CRT bugs 'disappeared'. Where I had reported buffer overruns (I actually had none at all) when a delete[] call was made, disappeared when I started to use this type of method.

And being templates, they can be specialized for the intrinsic types. obj->Type() on a built in type will just set it to 0, and obj->~Type() has no effect.

You could specialize the template for say int and remove constructor and destructor calls altogether.

I think the standard should define that the new/delete/[] operators should be templates. It's alot easier to specialize a template than it is to set a 'new allocator' for new/new[] to use. Or to override new/delete/[] for every class you want special allocation for.

George2
November 26th, 2007, 02:14 AM
Thanks JamesSchumacher,


I do not quite understand this statement,

pStart->Type(); // construct the object

in function NewArray,

In my understanding, pStart is some row memory you allocated with Windows API AllocateMemory, it is just some row data, then you convert it (forcelly) to Type, then invokes its constructor?

My confusion is, the constructor is a member function of Type, then pStart must be a pointer to Type other than raw memory.

Please feel free to correct me if I am wrong.

If you bypass mainCRTStartup or WinMainCRTStartup (depending on the application type) then you miss out on having global variables have 'auto initialization' and you cannot have static C++ objects. (No startup code to call constructors, and for that fact, with no runtime, do destructor calls either)

So pretty much you want to remove CRT dependence.

This is easy with a *.dll - not so easy with an application.

For a dll, make your entry point DllMainCRTStartup with the same signature as a regular DllMain, and 'link' against the Dll Runtime, then set the linker option to 'no default libraries'. Then you will have to add an *.lib files manually (windows libs for example, or other user *.dlls) that you want to use.

Just keep in mind that any global variables will not be initialized.

Also, understand without the C Runtime, you cannot use exception handling and other mechanisms that depend on the CRT. (__CxxThrowException)

If I remember correctly, without the C Runtime, new[] and delete[] become useless... If I remember correctly, it has something to do with the linker complaining about a missing 'scalar deleting destructor' reference.

In other words, if you use C++, new and delete are fine without the C Runtime (with Microsoft's compiler), but you will have to write a template function to simulate new[] and delete[]. This can be accomplished by prefixing a data buffer with a structure holding information about the array. Things like the number of objects, the size of each object (for debugging purposes), etc....

In this manner you will have to call constructors and destructors explicitly.


void * __stdcall AllocateMemory(unsigned long dwSize);
void __stdcall FreeMemory(void * lpBuf);

struct ArrayData
{
unsigned long ObjectSize;
unsigned long ObjectCount;
};

template <typename Type> Type * NewArray(unsigned long dwCount)
{
const unsigned long dwAllocSize = (dwCount * sizeof(Type)) + sizeof(ArrayData);

unsigned char * lpBuffer = reinterpret_cast<unsigned char *>(AllocateMemory(dwAllocSize));

if (lpBuffer != 0)
{
ArrayData * pPrefixData = reinterpret_cast<ArrayData *>(lpBuffer);

pPrefixData->ObjectSize = sizeof(Type);
pPrefixData->ObjectCount = dwCount;

ArrayData * pTemp = pPrefixData + 1;
Type * pTypeBuffer = reinterpret_cast<Type *>(pTemp);

Type * pStart = pTypeBuffer;
Type * pEnd = pTypeBuffer + dwCount;

while (pStart < pEnd)
{
pStart->Type(); // construct the object
++pStart;
}
}
}

template <typename Type> void DeleteArray(Type * pArray)
{
if (pArray != 0)
{
ArrayData * pData = reinterpret_cast<ArrayData *>(pArray);
pData = pData - 1;

const unsigned long dwCount = pData->ObjectCount;

Type * pEnd = pArray + dwCount;

while (pArray < pEnd)
{
pArray->~Type();
++pArray;
}

FreeMemory(pData);
}
}


The ironic thing is, I used this technique in the past, and CRT bugs 'disappeared'. Where I had reported buffer overruns (I actually had none at all) when a delete[] call was made, disappeared when I started to use this type of method.

And being templates, they can be specialized for the intrinsic types. obj->Type() on a built in type will just set it to 0, and obj->~Type() has no effect.

You could specialize the template for say int and remove constructor and destructor calls altogether.

I think the standard should define that the new/delete/[] operators should be templates. It's alot easier to specialize a template than it is to set a 'new allocator' for new/new[] to use. Or to override new/delete/[] for every class you want special allocation for.


regards,
George

JamesSchumacher
November 26th, 2007, 09:35 AM
The line:


pObject->Type(); // construct the object


Is calling the default constructor for the object. If this code is used on a type like int or long, the value will just be initialized to 0.

What I did was allocate a data buffer that is equal to sizeof(PrefixData) + sizeof(Type).

At the base is the prefix data, increment it to get to what would be the next of that type if it was an array of that type (that is, get to a valid point to cast to the correct type), then cast the pointer to the correct type, and call the default constructor.

George2
November 26th, 2007, 10:16 AM
Hi JamesSchumacher,


I have also write some code which has similar functions as yours, but it does not work. Could you help to find what is wrong with my code please? :-)

My code (in design) should work in the following way similar to your code,

1. Allocate a buffer which is enough to contain one object instance;
2. Forcelly convert the type of the buffer to object type;
3. Invoke the constructor.

But there is a compile error, how to make my code works similar to your code to initialize only one object instance? ;)


#include <iostream>

using namespace std;

class Foo {

private:

int i;

public:

Foo ()
{
i = 100;
cout << "constructor" << i << endl;
}

~Foo ()
{
cout << "destructor" << endl;
}

};

int main (int argc, char** argv)
{
char* p = new char [sizeof (Foo)];
((Foo*)p)->Foo();

delete[] p;
}


Error 1 error C2273: 'function-style cast' : illegal as right side of '->' operator main.cpp 31

The line:


pObject->Type(); // construct the object


Is calling the default constructor for the object. If this code is used on a type like int or long, the value will just be initialized to 0.

What I did was allocate a data buffer that is equal to sizeof(PrefixData) + sizeof(Type).

At the base is the prefix data, increment it to get to what would be the next of that type if it was an array of that type (that is, get to a valid point to cast to the correct type), then cast the pointer to the correct type, and call the default constructor.


regards,
George

Hermit
November 26th, 2007, 10:44 AM
Try placement new:

char * buf = new char [sizeof (Foo)];
Foo * obj = new (buf) Foo(); // placement new on preallocated memory

obj->~Foo(); // call destructor explicitly
delete [] buf;


Not even sure why you're trying to do this, but I'm pretty sure that's how it's done.

JamesSchumacher
November 26th, 2007, 12:08 PM
I knew how to remove CRT dependence from an app/dll on a Microsoft compiler, I just found out how to for MinGW when using Codeblocks.

DllMainCRTStartup (mainCRTStartup, WinMainCRTStartup) entry point... Also go to the linker options and give the option -nostdlib.

It's pretty simple. Writing *.dlls with no dependence on any other at all is pretty nice. ;)

However, on MinGW it looks as if virtual functions (atleast by normal means) are out of the question, due to the fact that the linker complains about the missing VTable for std::typeinfo.

Actually, I just found a workaround if you want to use C++ classes with virtual functions.

Put the following in one of your source files.


namespace __cxxabiv1
{
class __class_type_info
{
public:
virtual ~__class_type_info()
{
}
};
}


Apparently, I was wrong... It is NOT THAT EASY.

Guess it would take ALOT of work with MinGW. Visual C++ is as simple as just removing the CRT dependence, and possibly turning off RTTI.

Hermit
November 26th, 2007, 02:49 PM
It's pretty simple. Writing *.dlls with no dependence on any other at all is pretty nice. ;)
Honestly, I don't see the benefit in that. The CRT always ships with Windows, which is (more or less) the only system on which a .dll will run. And what about kernel32? Try and remove that dependency.

JamesSchumacher
November 27th, 2007, 09:03 AM
Honestly, I don't see the benefit in that. The CRT always ships with Windows, which is (more or less) the only system on which a .dll will run. And what about kernel32? Try and remove that dependency.

You cannot for an *.exe, you can for *.dlls.

In fact, Check my public folder at http://cpplibs.spaces.live.com and go into the Freeware Libraries folder. If you check DMGAPI.dll (in the *.zip file) with depends.exe from www.dependencywalker.com, you will note it has no dependency at all.

Of course, to load the *.dll - the application either calls LoadLibrary implicitly or explicitly, so technically... It would be VERY HARD to remove true dependency on Kernel32.dll ...

So unless it's a *.dll library project that requires no loading of other *.dlls (utility functions, classes) and no need for dynamic memory (you would need a call into Kernel32.dll) it's possible to write *.dlls that have no direct dependency.

EDIT...

There is a reason to remove CRT dependence. I am writing a C library in C++ (that is using C++ as a better C - I have heard that many times). The following header I have implemented all of these functions plus some internal ones. Keep in mind that I do use Kernel32.dll as a dependency... That's a given... However, by doing this in a 'C' manner, and exporting by ordinal... The 14 exports + the internal functions add up to making only a 4096 byte *.dll with MinGW.


#ifndef __JSCRT_H__
#define __JSCRT_H__

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#include <pshpack8.h>

typedef char SByte,Int8;
typedef unsigned char Byte,UInt8;
typedef short Short,Int16;
typedef unsigned short UShort,UInt16;
typedef long Int32;
typedef unsigned long UInt32;
typedef int Integer;
typedef unsigned int UInteger;
typedef float Single,Float;
typedef double Double;
typedef long long Int64;
typedef unsigned long long UInt64;

typedef int Boolean;
#define True 1
#define False 0

void * __stdcall CRT_Allocate(UInt32 dwSize);
Boolean __stdcall CRT_Free(void * lpBuf);
void __stdcall CRT_MemCopy(void * lpDest,const void * lpSource,UInt32 dwSize);
void __stdcall CRT_MemMove(void * lpDest,const void * lpSource,UInt32 dwSize);

typedef struct __CRT_ANSISTRING
{
void (__stdcall * Destructor)(__CRT_ANSISTRING * pString);
/* Member Variables */
SByte * Buffer;
UInt32 Capacity;
UInt32 Length;
UInt32 BlockSize;
} CRT_ANSISTRING;

UInt32 __stdcall CRT_StrLen(const SByte * pString);

UInt32 __stdcall CRT_GetDefaultStringBlockSize();
void __stdcall CRT_SetDefaultStringBlockSize(UInt32 dwSize);

CRT_ANSISTRING * __stdcall CRT_CreateString();
CRT_ANSISTRING * __stdcall CRT_CreateStringInit(const SByte * pString);
CRT_ANSISTRING * __stdcall CRT_CreateStringBufSpec(UInt32 dwCapacity,UInt32 dwBlockSize);

void __stdcall CRT_DeleteObject(void * lpCrtObject);

Boolean __stdcall CRT_StringReserve(CRT_ANSISTRING * pString,UInt32 dwCapacity,Boolean bKeepData);
Boolean __stdcall CRT_StringAppendChar(CRT_ANSISTRING * pString,SByte chValue,UInt32 dwCount);
Boolean __stdcall CRT_StringAppendStr(CRT_ANSISTRING * pString,const SByte * pstrAppend);

#include <poppack.h>

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* !defined __JSCRT_H__ */

George2
November 28th, 2007, 02:06 AM
Thanks Hermit,


Try placement new:

char * buf = new char [sizeof (Foo)];
Foo * obj = new (buf) Foo(); // placement new on preallocated memory

obj->~Foo(); // call destructor explicitly
delete [] buf;


Not even sure why you're trying to do this, but I'm pretty sure that's how it's done.

Your code will cause application crash. This line,

Foo * obj = new (buf) Foo(); // placement new on preallocated memory

Run-Time Check Failure #3 - The variable 'obj' is being used without being initialized.

I am using Visual Studio 2005.


regards,
George

George2
November 28th, 2007, 02:13 AM
Thanks JamesSchumacher,


I knew how to remove CRT dependence from an app/dll on a Microsoft compiler, I just found out how to for MinGW when using Codeblocks.

DllMainCRTStartup (mainCRTStartup, WinMainCRTStartup) entry point... Also go to the linker options and give the option -nostdlib.

It's pretty simple. Writing *.dlls with no dependence on any other at all is pretty nice. ;)

However, on MinGW it looks as if virtual functions (atleast by normal means) are out of the question, due to the fact that the linker complains about the missing VTable for std::typeinfo.

Actually, I just found a workaround if you want to use C++ classes with virtual functions.

Put the following in one of your source files.


namespace __cxxabiv1
{
class __class_type_info
{
public:
virtual ~__class_type_info()
{
}
};
}


Apparently, I was wrong... It is NOT THAT EASY.

Guess it would take ALOT of work with MinGW. Visual C++ is as simple as just removing the CRT dependence, and possibly turning off RTTI.

What is the purpose and benefits we can get if we remove the dependencies of CRT? CRT is C Runtime Library, in my previous knowledge, it is very critical, seems you want to do some hacking things to replace Windows default ones.


regards,
George

George2
November 28th, 2007, 02:15 AM
Hi Hermit,


What benefits we can get if we remove the dependency of kernel32?

Honestly, I don't see the benefit in that. The CRT always ships with Windows, which is (more or less) the only system on which a .dll will run. And what about kernel32? Try and remove that dependency.


regards,
George

George2
November 28th, 2007, 02:31 AM
Hi JamesSchumacher,


Cool! You are working on so system level things. I can roughly understand what you are doing, but why do you need to remove CRT dependencies? Could you provode more information please?

You cannot for an *.exe, you can for *.dlls.

In fact, Check my public folder at http://cpplibs.spaces.live.com and go into the Freeware Libraries folder. If you check DMGAPI.dll (in the *.zip file) with depends.exe from www.dependencywalker.com, you will note it has no dependency at all.

Of course, to load the *.dll - the application either calls LoadLibrary implicitly or explicitly, so technically... It would be VERY HARD to remove true dependency on Kernel32.dll ...

So unless it's a *.dll library project that requires no loading of other *.dlls (utility functions, classes) and no need for dynamic memory (you would need a call into Kernel32.dll) it's possible to write *.dlls that have no direct dependency.

EDIT...

There is a reason to remove CRT dependence. I am writing a C library in C++ (that is using C++ as a better C - I have heard that many times). The following header I have implemented all of these functions plus some internal ones. Keep in mind that I do use Kernel32.dll as a dependency... That's a given... However, by doing this in a 'C' manner, and exporting by ordinal... The 14 exports + the internal functions add up to making only a 4096 byte *.dll with MinGW.


#ifndef __JSCRT_H__
#define __JSCRT_H__

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#include <pshpack8.h>

typedef char SByte,Int8;
typedef unsigned char Byte,UInt8;
typedef short Short,Int16;
typedef unsigned short UShort,UInt16;
typedef long Int32;
typedef unsigned long UInt32;
typedef int Integer;
typedef unsigned int UInteger;
typedef float Single,Float;
typedef double Double;
typedef long long Int64;
typedef unsigned long long UInt64;

typedef int Boolean;
#define True 1
#define False 0

void * __stdcall CRT_Allocate(UInt32 dwSize);
Boolean __stdcall CRT_Free(void * lpBuf);
void __stdcall CRT_MemCopy(void * lpDest,const void * lpSource,UInt32 dwSize);
void __stdcall CRT_MemMove(void * lpDest,const void * lpSource,UInt32 dwSize);

typedef struct __CRT_ANSISTRING
{
void (__stdcall * Destructor)(__CRT_ANSISTRING * pString);
/* Member Variables */
SByte * Buffer;
UInt32 Capacity;
UInt32 Length;
UInt32 BlockSize;
} CRT_ANSISTRING;

UInt32 __stdcall CRT_StrLen(const SByte * pString);

UInt32 __stdcall CRT_GetDefaultStringBlockSize();
void __stdcall CRT_SetDefaultStringBlockSize(UInt32 dwSize);

CRT_ANSISTRING * __stdcall CRT_CreateString();
CRT_ANSISTRING * __stdcall CRT_CreateStringInit(const SByte * pString);
CRT_ANSISTRING * __stdcall CRT_CreateStringBufSpec(UInt32 dwCapacity,UInt32 dwBlockSize);

void __stdcall CRT_DeleteObject(void * lpCrtObject);

Boolean __stdcall CRT_StringReserve(CRT_ANSISTRING * pString,UInt32 dwCapacity,Boolean bKeepData);
Boolean __stdcall CRT_StringAppendChar(CRT_ANSISTRING * pString,SByte chValue,UInt32 dwCount);
Boolean __stdcall CRT_StringAppendStr(CRT_ANSISTRING * pString,const SByte * pstrAppend);

#include <poppack.h>

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* !defined __JSCRT_H__ */



regards,
George

ovidiucucu
November 28th, 2007, 05:05 AM
Just my two (euro)cents...

In the real programming world, there are rare cases in which those optimizations are in the first place berfore the code readability and maintenability and coding productivity. Usually, very few users will jump and joy "look mommy, I've got an only 4k module with no (CRT) dependences!..." ;).
No mention how happy can be other programmers dealing with that code.
As for example, I can read the above code which has about 50 lines, but I wouldn't like to manage a similar one having few thousands.

Although, it's nothing wrong to dig, to try, to discuss, and know that such types of (extreme) optimization techniques exist.


[ Late edit ]
I hope this link (http://www.catch22.net/tuts/minexe.asp) can be interesting for you.

JamesSchumacher
November 28th, 2007, 09:28 AM
Hi JamesSchumacher,


Cool! You are working on so system level things. I can roughly understand what you are doing, but why do you need to remove CRT dependencies? Could you provode more information please?




regards,
George

Actually, my goal when I can get access to a Microsoft C++ compiler (cannot install here due to administrative limitations) I want to roll my own minimal C Runtime.

And in doing so, if a C Runtime *.dll is to be used, if there is going to be 'bloat', I want that C Runtime to have better functionality than the one provided. Another reason? I am in the process of wrapping SDL at the moment in an easy to use C++ set of classes... And I am going to try and write a platform independent window (polling) + game (sampling) management system.

If you check the Demos folder, in my SDL folder of RPGXtreme (it will be first used for that game to test it...) you can see that I am using SDL and SDL_ttf.

Download the *.exe right now (and dependent *.dlls) and you can see I have written a custom routine called 'GradientToPoint'.

George2
November 29th, 2007, 12:31 AM
Thanks JamesSchumacher,


Cool! You mean you are using Microsoft compiler (SDK? including CRT or other libraries) and you are using your own C Runtime?

In my previous knowledge, compiler (SDK) should be compatible with runtime, seems that you can break this rule to use Microsoft SDK and your own runtime?

Actually, my goal when I can get access to a Microsoft C++ compiler (cannot install here due to administrative limitations) I want to roll my own minimal C Runtime.

And in doing so, if a C Runtime *.dll is to be used, if there is going to be 'bloat', I want that C Runtime to have better functionality than the one provided. Another reason? I am in the process of wrapping SDL at the moment in an easy to use C++ set of classes... And I am going to try and write a platform independent window (polling) + game (sampling) management system.

If you check the Demos folder, in my SDL folder of RPGXtreme (it will be first used for that game to test it...) you can see that I am using SDL and SDL_ttf.

Download the *.exe right now (and dependent *.dlls) and you can see I have written a custom routine called 'GradientToPoint'.


regards,
George

JamesSchumacher
November 29th, 2007, 08:58 AM
Thanks JamesSchumacher,


Cool! You mean you are using Microsoft compiler (SDK? including CRT or other libraries) and you are using your own C Runtime?

In my previous knowledge, compiler (SDK) should be compatible with runtime, seems that you can break this rule to use Microsoft SDK and your own runtime?




regards,
George

At the moment I am not using Microsoft's compiler because I cannot install it in the location I have computer access. If I did, I would use Visual C++ 2008 Express. However, since I cannot... I am using Code::Blocks with MinGW at the moment.

I can remove C Runtime dependence on MinGW if I program C like with at best classes with no virtual functions.

Yeah, you can write your own C runtime *.dll - The Windows *.dlls do not import from MSVCRT/MSVCR71/MSVCR80/etc... *.dlls, which means it doesn't matter what the name of your runtime *.dll is, therefore... As long as all your modules and apps use the custom CRT *.dll, you are okay.

George2
November 29th, 2007, 09:19 AM
Cool JamesSchumacher!


At the moment I am not using Microsoft's compiler because I cannot install it in the location I have computer access. If I did, I would use Visual C++ 2008 Express. However, since I cannot... I am using Code::Blocks with MinGW at the moment.

I can remove C Runtime dependence on MinGW if I program C like with at best classes with no virtual functions.

Yeah, you can write your own C runtime *.dll - The Windows *.dlls do not import from MSVCRT/MSVCR71/MSVCR80/etc... *.dlls, which means it doesn't matter what the name of your runtime *.dll is, therefore... As long as all your modules and apps use the custom CRT *.dll, you are okay.

Do you open source or plan to open source of what you are doing? If you are doing so, I would like to have a copy of code to learn from you. A customzied C/C++ Runtime -- looks cool and hacking. ;) :thumb:


regards,
George

JamesSchumacher
November 29th, 2007, 03:03 PM
Cool JamesSchumacher!




Do you open source or plan to open source of what you are doing? If you are doing so, I would like to have a copy of code to learn from you. A customzied C/C++ Runtime -- looks cool and hacking. ;) :thumb:


regards,
George

Yes, the runtime library that I write is going to be open source, so you can have a copy of it when I do release that.

At the moment, I am more diving deeper into SDL and implementing custom routines and some game states for my RPG I am writing in the process.

You can check out the results so far in my demos folder of my spaces.live.com account. C++ Libraries (http://cpplibs.spaces.live.com)

I can do 'manual' vtables with MinGW without the C runtime... In fact, I will write up a quick C implementation of a class and post it in the Freeware Libraries folder. (It will have it's source within the *.zip file)

JamesSchumacher
November 29th, 2007, 05:32 PM
You can check out PLATLIB, I started on this today. It is going to be a combined C/C++ Runtime Library. However, the OOP C++ part is going to have to wait until I have access to a MS VC++ compiler, lack of virtual functions is not fun. However, I could do all the implementation manually, and in the C++ section just create a struct object and cast it to the appropriate defined interface type.

We will see.

PLATLIB (http://cid-f7d26664ce20e649.skydrive.live.com/self.aspx/Public/Freeware%20Libraries/PLATLIB%20-%20C%20CPlusPlus%20Runtime%20Library)

Do not mind that I have the SDL development package in the *.zip - it is going to employ SDL because I am going to write a window manager. :thumb:

George2
November 30th, 2007, 02:25 AM
Thanks JamesSchumacher,


You can check out PLATLIB, I started on this today. It is going to be a combined C/C++ Runtime Library. However, the OOP C++ part is going to have to wait until I have access to a MS VC++ compiler, lack of virtual functions is not fun. However, I could do all the implementation manually, and in the C++ section just create a struct object and cast it to the appropriate defined interface type.

We will see.

PLATLIB (http://cid-f7d26664ce20e649.skydrive.live.com/self.aspx/Public/Freeware%20Libraries/PLATLIB%20-%20C%20CPlusPlus%20Runtime%20Library)

Do not mind that I have the SDL development package in the *.zip - it is going to employ SDL because I am going to write a window manager. :thumb:

Good learning resource. Thanks again.


regards,
George