我有以下用非托管C代码编写的程序:
#include <Windows.h>
#include <tchar.h>
const TCHAR g_szClassName[] = _T("SkeletonAppWindowClass");
LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam);
ATOM RegisterWCEX(HINSTANCE hInstance);
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd);
ATOM RegisterWCEX(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.hbrBackground = (HBRUSH)COLOR_WINDOW;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hIcon =
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WindowProc;
wcex.lpszClassName = g_szClassName;
return RegisterClassEx(&wcex);
}
BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam)
{
HFONT hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hWnd, WM_SETFONT, (WPARAM)hfDefault, 0L);
return TRUE;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
static HWND hButton;
switch (Msg)
{
case WM_CREATE:
hButton = CreateWindow(_T("BUTTON"), _T("Say Hi"), WS_VISIBLE | WS_CHILD, 130, 230, 70, 20, hWnd, NULL, GetModuleHandle(NULL), NULL);
break;
case WM_COMMAND:
if ((HWND)lParam == hButton)
{
MessageBox(0, _T("Hello World!"), _T("Information"), MB_OK | MB_ICONINFORMATION);
}
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return 0;
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
{
HWND hWnd;
MSG Msg;
RegisterWCEX(hInstance);
hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, g_szClassName, _T("Simple Window"), WS_VISIBLE | WS_SYSMENU, 100, 100, 350, 370, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, SW_SHOW);
EnumChildWindows(hWnd, EnumChildProc, 0L);
UpdateWindow(hWnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
所有这一切都是创建一个简单的窗口,当点击它时会弹出一个显示“Hello World!”的消息框。
此程序在发布模式下的大小为10KB,并且/O1
(最小化空间)优化。
然后,当我在C#中创建“Windows窗体应用程序”并在窗体上创建一个按钮,其事件处理程序是这样的:
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello World", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
在发布模式下编译时,C#可执行文件的大小仅为8KB。这是违反直觉的;我原以为非托管程序会更加紧凑。
问题是我编写C程序的方式,还是还有其他我没有考虑过的问题?
答案 0 :(得分:1)
您的程序的大多数功能都包含在您链接到的库中。这些库不会影响程序的大小,除非他们采取更多函数调用来执行相同的行为。在你的例子中就是这种情况。 Windows库需要大量的设置和调用API来生成一个对话框,与.NET应用程序相比,它只需要一个函数调用,而且没有配置。编译程序的大小与链接和调用库的外部API的指令数有关。非托管程序比使用.NET的程序有更多指令。
答案 1 :(得分:1)
编译机器代码是在运行时。你的代码(libaries)的功能是与你的.NET一起安装的。因此,您的应用程序较小,因为它使用您安装的PC库。