Multithreaded-DLL
-
Hi!
Ich will im VS2005 Standard reine WinApi Programmierung machen. In den Einstellungen sieht auch alles sehr gut aus:
Verwendung von MFC: Windows-Standardbibliotheken verwenden
Verwendung von ATL: ATL wird nicht verwendet
CLR-Unterstützung: Nein
[...]
Aber im Bereich Codegenerierung hab ich das hier entdeckt:
Laufzeitbibliotek: Multihreaded-DLL
Mit dieser Einstellung werden die Programme nur erfreuliche 10kb groß. Wenn ich auf Multithreaded (ohne DLL) umstelle komm ich auf über 400.
Ist diese Multithreaded-DLL standardmäßig auf Windows-PCs vorhanden oder muss ich sie wirklich dazulinken?
-
[Schwachsinn, Sorry
]
-
Naja ich will mich mit der WinApi beschäftigen um sehr kleine Programme zu erstellen (auch wenn das heute lächerlich klingt
). Sonnst kann ich ja auch beim Borland C++Builder bleiben und die VCL mit mir rumschleppen.
-
Nein da hast Du allerdings vollkommen Recht
! Hab ich irgendwie grad nicht dran gedacht
... . Glaub ich sollte beim posten nit so viel AC/DC hören
.
-
CodeFinder schrieb:
Die sind eigenltich immmer dabei.
Blödsinn! Bei VS2005 heissen die DLLs msvcr80.dll / msvcp80.dll / msvcm80.dll und sind bei (fast) keinem OS dabei!!! (möglicherweise bei Vista; aber sonst 100%ig bei keinem anderen).
Wenn Du *ganz* kleine Programme erstellen willst, dann verzichte auf die CRT und stelle einen eigenen Entry-Point zur Verfügung!
-
Sry ich versteh nur Bahnhof

Also soll ich auf das Benutzen der C-Standardbibliothek verzichten. Heißt das ich darf eigentlich nur die windows.h benutzen?
Und was du mit "eigenem Entry-Point" meinst weiß ich leider auch nicht.
-
Ok im Release-Mode wird die Datei mit DLL 7 kb groß ohne DLL 64 kb. Das ist noch annehmbar. Wenn ich damit auf der sicheren Seite bin werd ich mich wohl damit zufriedengeben müssen.
-
Spieler schrieb:
Also soll ich auf das Benutzen der C-Standardbibliothek verzichten. Heißt das ich darf eigentlich nur die windows.h benutzen?
Ja. Dann kannst Du Programme schreiben sie so klein wie möglich sind...
Spieler schrieb:
Und was du mit "eigenem Entry-Point" meinst weiß ich leider auch nicht.
In den Projekteinstellungen unter "Linker|Advanced|Entry Point" oder "/ENTRY:"
-
Wenn Du *ganz* kleine Programme erstellen willst, dann verzichte auf die CRT und stelle einen eigenen Entry-Point zur Verfügung!
Weisst du was dann alles nichtmehr geht, wenn man keine CRT linkt? Und was man für nen Tanz aufführen muss dass überhaupt noch *irgendwas* geht ohne CRT? Also zumindest mit dem VS ist das ein echter Krampf, ganz ganz grausam.
Da würde ich mich eher nach einem anderen Compiler umsehen... vielleicht mal sehen was mit dem g++ oder Digital Mars so geht.Oder eben, sicherste Möglichkeit, nen guten optimierenden Macro Assembler nehmen :^)
-
hustbaer schrieb:
Wenn Du *ganz* kleine Programme erstellen willst, dann verzichte auf die CRT und stelle einen eigenen Entry-Point zur Verfügung!
Weisst du was dann alles nichtmehr geht, wenn man keine CRT linkt?
Was meinst Du damit? Die CRT ist nur ein "Aufsatz" auf der WinAPI. Somit kannst Du auch ohne CRT alles machen, was man sonst auch machen kann

hustbaer schrieb:
Und was man für nen Tanz aufführen muss dass überhaupt noch *irgendwas* geht ohne CRT? Also zumindest mit dem VS ist das ein echter Krampf, ganz ganz grausam.
Was meinst Du damit?
Die Release-Version von Folgendem Programm:#include <windows.h> #pragma comment(linker, "/ENTRY:myMain") extern "C" int __stdcall myMain() { ExitProcess(0); }hat keinerlei Abhängigkeiten zur CRT...
Auch ist die Datei ganze 2,944 Bytes gross.
Nach deaktivieren der Debug-Infos und abschalten des eingebetten Manifests ist es noch 2,048 Bytes gross.
Und ein "dumpbin /ALL" erzeugt:Microsoft (R) COFF/PE Dumper Version 8.00.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.Dump of file CPP_OhneCRT.exe
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (x86)
3 number of sections
458B8284 time date stamp Fri Dec 22 08:00:20 2006
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
103 characteristics
Relocations stripped
Executable
32 bit word machineOPTIONAL HEADER VALUES
10B magic # (PE32)
8.00 linker version
200 size of code
600 size of initialized data
0 size of uninitialized data
1000 entry point (00401000)
1000 base of code
2000 base of data
400000 image base (00400000 to 00403FFF)
1000 section alignment
200 file alignment
4.00 operating system version
0.00 image version
4.00 subsystem version
0 Win32 version
4000 size of image
400 size of headers
0 checksum
3 subsystem (Windows CUI)
400 DLL characteristics
No structured exception handler
100000 size of stack reserve
1000 size of stack commit
100000 size of heap reserve
1000 size of heap commit
0 loader flags
10 number of directories
0 [ 0] RVA [size] of Export Directory
2010 [ 28] RVA [size] of Import Directory
0 [ 0] RVA [size] of Resource Directory
0 [ 0] RVA [size] of Exception Directory
0 [ 0] RVA [size] of Certificates Directory
0 [ 0] RVA [size] of Base Relocation Directory
0 [ 0] RVA [size] of Debug Directory
0 [ 0] RVA [size] of Architecture Directory
0 [ 0] RVA [size] of Global Pointer Directory
0 [ 0] RVA [size] of Thread Storage Directory
0 [ 0] RVA [size] of Load Configuration Directory
0 [ 0] RVA [size] of Bound Import Directory
2000 [ 8] RVA [size] of Import Address Table Directory
0 [ 0] RVA [size] of Delay Import Directory
0 [ 0] RVA [size] of COM Descriptor Directory
0 [ 0] RVA [size] of Reserved DirectorySECTION HEADER #1
.text name
9 virtual size
1000 virtual address (00401000 to 00401008)
200 size of raw data
400 file pointer to raw data (00000400 to 000005FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
Execute ReadRAW DATA #1
00401000: 6A 00 FF 15 00 20 40 00 CC j.ÿ.. @.ÌSECTION HEADER #2
.rdata name
5C virtual size
2000 virtual address (00402000 to 0040205B)
200 size of raw data
600 file pointer to raw data (00000600 to 000007FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
Read OnlyRAW DATA #2
00402000: 40 20 00 00 00 00 00 00 00 30 40 00 58 30 40 00 @ .......0@.X0@.
00402010: 38 20 00 00 00 00 00 00 00 00 00 00 4E 20 00 00 8 ..........N ..
00402020: 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 . ..............
00402030: 00 00 00 00 00 00 00 00 40 20 00 00 00 00 00 00 ........@ ......
00402040: 04 01 45 78 69 74 50 72 6F 63 65 73 73 00 4B 45 ..ExitProcess.KE
00402050: 52 4E 45 4C 33 32 2E 64 6C 6C 00 00 RNEL32.dll..Section contains the following imports:
KERNEL32.dll
402000 Import Address Table
402038 Import Name Table
0 time date stamp
0 Index of first forwarder reference104 ExitProcess
SECTION HEADER #3
.data name
324 virtual size
3000 virtual address (00403000 to 00403323)
0 size of raw data
0 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
Read WriteSummary
1000 .data
1000 .rdata
1000 .textAlso ich finde es überhaupt nicht schwierig... oder was hast Du gemeint?
-
sehe ich das richtig das ein manifest nur dann benötigt wird wenn man die CRT 8 verwendet? ich versuche nämlich auch schon seit längerem meine appgröße im relase möglichst klein zu halten und bekam die CRT bisher einfach nicht raus. das hat teilweise auch schon dazu geführt das auf manchen systemen meine anwendung erst garnicht starten wollte. (FM: Fehler in Anwendungskonfiguration, installieren Sie die anwendung neu oder ähnlich) ich brauch die CRT nämlich auch nicht wirklich, das bissle strings hin und herkopieren kann man au selbst implementieren oder aus den win limps importiern (lstrcmp, lstrcpy, ...)
meine app ist ein reiner server benötigt keine CRT, kein manifest und soll auf allen win systemen laufen ohne zusätzliche dll's.gibts vllt irgendwo tutorials zur größenoptimierung mit VS2005 wenn man REINE winapi apps machen möchte? bin in der richtung noch ned so fit.
MfG
RadiatioN
-
@Jochen: Wenn wir bei C bleiben OK.
Wie sieht das mit C++ aus, wenn dann statische/globale Objekte hinzukommen? new/delete sind IMHO komplett Abhängig von der CRT... oder irre ich mich da?
-
Martin Richter schrieb:
@Jochen: Wenn wir bei C bleiben OK.
Wie sieht das mit C++ aus, wenn dann statische/globale Objekte hinzukommen? new/delete sind IMHO komplett Abhängig von der CRT... oder irre ich mich da?Hmm... bei C++ wird es etwas komplexer, da hier noch vom Compiler spezielle Funktionen erwartet werden.
Das Folgende Beispiel hat z.B: auch keinerlei Abhängigkeiten zur CRT:#include <windows.h> #pragma comment(linker, "/ENTRY:myMain") void* operator new(size_t size) { void *p = HeapAlloc(GetProcessHeap(), 0, size); //if (p == 0) // throw 0; return (p); } void operator delete(void *pUserData) { if (pUserData != NULL) HeapFree(GetProcessHeap(), 0, pUserData); } class A { public: A() { a = 11; b = 2; } void Out() { DWORD dwWritten; WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "Hello world", a, &dwWritten, NULL); } DWORD a; int b; }; extern "C" int __stdcall myMain() { A a; A *pa = new A(); pa->Out(); delete pa; ExitProcess(0); }Wenn Du das "throw" wieder reinnimmst, dann wird es kompliziert... dieses hier ist jetzt vollkommen Compiler-Spezifisch... kann aber auch ersetzt werden, wenn Du weisst, was der Compiler genau erwartet.
Das scheint mir auch der einzige Code-Teil der CRT zu sein, welcher nicht bei den Sourcen dabei ist!
Hier findet sich z.B: mehr darüber:
http://www.ddj.com/dept/windows/184416600Folgendes ist dann der (Test-)Code mit C++-Exceptions, welches auch keinerlei Abhängigkeiten zur CRT hat:
#include <windows.h> #pragma comment(linker, "/ENTRY:myMain") // TODO: Linker-Options: /NODEFAULTLIB:msvcrt.lib" void* operator new(size_t size) { void *p = HeapAlloc(GetProcessHeap(), 0, size); if (p == 0) throw 0; return (p); } void operator delete(void *pUserData) { if (pUserData != NULL) HeapFree(GetProcessHeap(), 0, pUserData); } class type_info { public: virtual ~type_info() {} bool operator==(const type_info& rhs) const {return false;} bool operator!=(const type_info& rhs) const {return false;} int before(const type_info& rhs) const {return 0;} const char* name() const {return 0;} const char* raw_name() const {return 0;} }; const DWORD CPP_EXCEPTION = 0xE06D7363; const DWORD MS_MAGIC = 0x19930520; extern "C" void __stdcall _CxxThrowException(void * pObject, _s__ThrowInfo const * pObjectInfo) { const ULONG_PTR args[] ={ MS_MAGIC, (ULONG_PTR)pObject, (ULONG_PTR)pObjectInfo }; RaiseException(CPP_EXCEPTION, EXCEPTION_NONCONTINUABLE, sizeof(args)/sizeof(args[0]), args); } class A { public: A() { a = 11; b = 2; } void Out() { DWORD dwWritten; WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "Hello world", a, &dwWritten, NULL); } DWORD a; int b; }; extern "C" int __stdcall myMain() { A a; A *pa = new A(); pa->Out(); delete pa; ExitProcess(0); }Und das mit den globalen Objekten wird man auch in der Griff bekommen, da ja hier die Sourcen vorliegen

-
@Jochen Kalmbach:
Genau solche Sachen meinte ich mit "fürchterlich kompliziert"
Sobald du Exceptions verwenden willst heisst es basteln. Sobald du dynamic_cast verwenden willst heisst es noch mehr basteln. RTTI im Allgemeinen -> basteln.
Weiters kannst du in deinem Programm zwar Exceptions werfen, aber nicht fangen. Stack Unwinding -> wieder in der CRT implementiert.Wenn man also reinen C-Code schreiben will, bzw. bloss "etwas schöneren C-Code" mit C++, dann geht es vielleicht. Trotzdem würde ich mich da eher nach einem Compiler umsehen wo man das etwas einfacher hinbekommt als mit dem MSVC
