https://www.youtube.com/embed/OOJqHPfG7pA
Monday, March 23, 2020
Sunday, January 26, 2020
Windows Application Development on Linux
Make sure you have installed MinGW on Linux:
sudo apt install mingw-w64 gdb-mingw-w64
Optionally, for testing purpose, install also WINE:
wine-stable wine-development wine64 wine64-development
FYI, with my recent mingw32 installation, the location for needed DLL files are in :
/usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/
ll /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/*.dll
-rwxr-xr-x 1 root root 482339 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libatomic-1.dll*
-rwxr-xr-x 1 root root 1190750 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libgcc_s_seh-1.dll*
-rwxr-xr-x 1 root root 1523015 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libgomp-1.dll*
-rwxr-xr-x 1 root root 1393636 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libquadmath-0.dll*
-rwxr-xr-x 1 root root 387526 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libssp-0.dll*
-rwxr-xr-x 1 root root 16229690 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libstdc++-6.dll*
Example of Makefile:
APP=MyGUI
CC=x86_64-w64-mingw32-g++
WRC=x86_64-w64-mingw32-windres
$(APP).exe : $(APP).o $(APP).res
$(CC) -mwindows $(APP).o $(APP).res -o $@
$(APP).o: $(APP).c
$(CC) -mwindows -c -o $@ $<
$(APP).res : resource.rc resource.h
$(WRC) $< -O coff -o $@
clean:
rm *.res *.o $(APP).exe
The Source code:
To run:
wine64 MyGUI.exe
If we find issue that WINE could not find some MinGW's *.dll, create soft links in WINE's system directory to the MinGW's dll:
pushd ~/.wine/drive_c/windows/system
cp -s /usr/lib/gcc/i686-w64-mingw32/7.3-win32/*.dll .
popd
To debug the EXE:
i686-w64-mingw32-gdb <EXE code>
sudo apt install mingw-w64 gdb-mingw-w64
Optionally, for testing purpose, install also WINE:
wine-stable wine-development wine64 wine64-development
FYI, with my recent mingw32 installation, the location for needed DLL files are in :
/usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/
ll /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/*.dll
-rwxr-xr-x 1 root root 482339 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libatomic-1.dll*
-rwxr-xr-x 1 root root 1190750 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libgcc_s_seh-1.dll*
-rwxr-xr-x 1 root root 1523015 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libgomp-1.dll*
-rwxr-xr-x 1 root root 1393636 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libquadmath-0.dll*
-rwxr-xr-x 1 root root 387526 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libssp-0.dll*
-rwxr-xr-x 1 root root 16229690 Mar 12 2018 /usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libstdc++-6.dll*
(this path should be added into PATH to make wine able to run our compiled EXE)
Example of Makefile:
APP=MyGUI
CC=x86_64-w64-mingw32-g++
WRC=x86_64-w64-mingw32-windres
$(APP).exe : $(APP).o $(APP).res
$(CC) -mwindows $(APP).o $(APP).res -o $@
$(APP).o: $(APP).c
$(CC) -mwindows -c -o $@ $<
$(APP).res : resource.rc resource.h
$(WRC) $< -O coff -o $@
clean:
rm *.res *.o $(APP).exe
The Source code:
/*-------------------------------------------------*/ /* MyGUI.c - gui hello world */ /* build: gcc -mwindows MyGUI.c -o MyGUI.exe */ /*-------------------------------------------------*/ #include <windows.h> char glpszText[1024]; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); /****************************************************************************** * Main entry ******************************************************************************/ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { wsprintf(glpszText, "Hello World\nGetCommandLine(): [%s]\n" "WinMain lpCmdLine: [%s]\n", lpCmdLine, GetCommandLine() ); WNDCLASSEX wcex; wcex.cbSize = sizeof(wcex); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; /* set the callback */ wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = "MYGUI"; wcex.hIconSm = NULL; if (!RegisterClassEx(&wcex)) return FALSE; HWND hWnd; hWnd = CreateWindow("MYGUI", "MyGUI", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); MSG msg; /* main loop */ while (GetMessage(&msg, NULL, 0, 0)) { /* we can intercept keystrokes here too if we want */ TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } /****************************************************************************** * Main callback ******************************************************************************/ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); RECT rt; GetClientRect(hWnd, &rt); DrawText(hdc, glpszText, strlen(glpszText), &rt, DT_TOP | DT_LEFT); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: /* for everything else unhandled, do this */ return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
To run:
wine64 MyGUI.exe
If we find issue that WINE could not find some MinGW's *.dll, create soft links in WINE's system directory to the MinGW's dll:
pushd ~/.wine/drive_c/windows/system
cp -s /usr/lib/gcc/i686-w64-mingw32/7.3-win32/*.dll .
popd
To debug the EXE:
i686-w64-mingw32-gdb <EXE code>
Thursday, January 9, 2020
To list (dir command) file names sorted by their name's length
Suppose we want to list certain files (or all files in a directory), but sorted ascending by their filename's length.
The following small script meets the purpose:
First, create a PowerShell script, say, dirnamesize.ps1 with its content as below:
param (
[string]$dirpath = "."
)
gci $dirpath | select-object name, @{Name="Nlength";Expression={$_.Name.Length}} | sort-object Nlength
Second, create a normal DOS shell file to call that PowerShell (so we don't need to open PowerShell), say, dirnamesize.cmd with the content:
set DIRPATH=%*
@if "%DIRPATH%"=="" (
powershell dirnamesize.ps1
) else (
powershell dirnamesize.ps1 -dirpath %DIRPATH%
)
Example:
C:\Windows>dirname *.xml
Name Nlength
---- -------
Education.xml 13
ServerRdsh.xml 14
Enterprise.xml 14
Professional.xml 16
ProfessionalEducation.xml 25
ProfessionalWorkstation.xml 27
Sunday, December 29, 2019
Example of Intrusive Singly Linked List
#include <stdio.h> #include <stdlib.h> #include <stddef.h> typedef struct list_item { int val; void *next; } list_item; typedef struct List { list_item *head; list_item *prev; } List; list_item *create_list_item(int val) { list_item *p = (list_item *)malloc(sizeof(list_item)); if (p) { p->val = val; p->next = NULL; } return p; } void add_list_item_into_node(List *list, int val) { list_item *newlist_item = create_list_item(val); if (list->prev != NULL) { list->prev->next = newlist_item; list->prev = newlist_item; } else { list->head = newlist_item; list->prev = newlist_item; printf("FIRST! head==prev ? %d, %p\n", list->head==list->prev, list->head); } printf("%p added; head=%p, prev=%p\n", newlist_item, list->head, list->prev); } void init_list(List *l) { l->head = l->prev = NULL; } void clear_list(List *l) { list_item *p = l->head; while (p != NULL) { list_item *pn = (list_item *)p->next; printf("Freeing %p, next p is=%p\n", p, pn); free(p); p = pn; } l->head = l->prev = NULL; } typedef void (*callback_t)(list_item *); void print(list_item *p) { printf("p=%p: val=%d\n", p, p->val); } void iterate(List *list, callback_t cbk) { list_item *p = list->head; while (p) { cbk(p); p = p->next; } } int main() { List mylist; init_list(&mylist); for(int i=0; i<10; ++i) { add_list_item_into_node(&mylist, i*2+1); } iterate(&mylist, print); // cleanup; starting from head printf("Cleaning up!\n"); clear_list(&mylist); iterate(&mylist, print); printf("head = %p, prev=%p\n", mylist.head, mylist.prev); }
Friday, September 20, 2019
Unique Pointer (Smart Pointer)
The following example shows how to use unique_ptr which semantically 'moves' the data during assignment:
#include <iostream> #include <memory> using namespace std; class MyClass { public: #if COMPILE_ERROR MyClass ( std::unique_ptr<int> const & pOpt = std::unique_ptr<int>(nullptr) ) : m_ptr(std::move(pOpt)) { } #else explicit MyClass ( std::unique_ptr<int> pOpt = std::unique_ptr<int>(nullptr) ) : m_ptr(std::move(pOpt)) { std::cout << __FUNCTION__ << "() : m_ptr=" << m_ptr.get() << std::endl; } MyClass() = delete; #endif friend ostream& operator<<(ostream& os, const MyClass& c); private: std::unique_ptr<int> m_ptr; }; template<typename T> std::unique_ptr<T>& pass_through(std::unique_ptr<T>& p) { if (p != nullptr) std::cout << *p << std::endl; else std::cout << "nullptr" << std::endl; return p; } ostream& operator<<(ostream& os, const MyClass& c) { if (c.m_ptr != nullptr) return os << __FUNCTION__ << "(): " << *c.m_ptr; else return os << __FUNCTION__ << "(): nullptr"; } int main() { std::unique_ptr<int> pInt(new int(15)); MyClass data(); MyClass data2(std::move(pInt)); pass_through(pInt); std::cout << "data = " << data << std::endl; std::cout << "data2 = " << data2 << std::endl; }
MyClass() : m_ptr=0x7430d0
nullptr
data = 1
data2 = operator<<(): 15
Wednesday, March 13, 2019
Callback via C++ template
The following code would make a callback via template:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <iostream> template <typename F> void call(F func) { func(); } void print() { std::cout << __FUNCTION__ << "()" << std::endl; } int main() { call(print); } |
Subscribe to:
Posts (Atom)