new / delete in C++
在C++中,new / delete 總共有三種用法。new跟delete的用法類似,所以就以new來示範。
operator new
詳細細節可以參考operator new和operator new, operator new[]
可以透過function overload訂製自己的new和delete動作。
operater new/delete就相對於C語言的malloc/free。因此透過operator new分配到的記憶體就該用operator delete釋放。
1 | struct Object { |
這時就會使用Object裡面的new/delete的函式了。
Placement new
Placement new只是operator new的一種overload版本
1 | inline void *operator new(size_t, void *_Where) |
詳細使用可以參考C++ FAQ中的介紹。
我們可以從任何記憶體位置(在Heap或是Stack都行)進行new constructor的動作。
1 | void *pMemory = malloc(sizeof(Object)); |
Placement new的存在是有意義的,可以自由控制Memory的取得方式,可以從Stack/Heap/Memory Pool中取得記憶體,對於某些情景之下有更大的
new operator
這大概是最常見的動作,基本上就是以下兩個步驟構成
- 呼叫 operator new
- 呼叫 Constructor
這個順序是固定的,無法opverload,這是C++ Standard所規定的。
How to output Intel's assembly syntax for gcc
看慣了x86的Intel Syntax,對於AT&T的語法還是不習慣。
使用以下方式可以將gcc編譯出來的Code變成Intel Syntax。
1 | $ gcc test.c -S -masm=intel |
這只支援gcc,clang不行。
Overloading postfix and prefix ++ in C++
突然想到,順手把他記下來吧。
在C++當中,如果要自己定義++和–這兩個operator,需要不同的Function signature。
1 | class Date { |
最大的差別就在於Postfix裡面有個未使用的參數。至於為什麼要這麼設計,可以參考這裡。
Creating Variable-size structs in C/C++
這種技巧很常在Open Source的專案中看到,看了Arrays of Length Zero原本以為是GCC獨有Extensionm,後來發現Clang跟VC都能使用,記錄一下。
1 | struct datapacket |
這邊的data[0]不佔記憶體空間,因此sizeof(struct datapacket)
大小相當於sizeof(int)
,而data就是一個記憶體指標,指向一塊連續的記憶體。
Write HelloWorld for LLVM IR
一直想寫一篇關於LLVM的文章,想了好久終於下筆了。 同樣從Hello world開始下手
1 | #include <stdio.h> |
編譯成 LLVM的IR中間形式,利用lli
來執行IR Code。
1 | $ clang hello.c -S -emit-llvm -o hello.lli |
刪除hello.lli的Meta data之後,一個Hello world的最小部分掌這個樣子
1 | @.str = private unnamed_addr constant [14 x i8] c"Hello world!\0A\00", align 1 |
Useful algorithms in real product
在StackExchange有人問了一個問題。在實際產品中常用的資料結構跟演算法有哪些。
把這當做一個參考,有空的時候可以研究一下。
How to call C/C++ code from Python
這篇文章正好是上一篇的相反行為。為了加速某些特殊運算,有時需要呼叫C/C++的程式碼。使用Python內建的ctypes可以幫助完成這件事。
1 | #include <iostream> |
將其編譯成Shared Library / DLL。
1 | $ g++ -c -fPIC foo.cpp -o foo.o |
接著就是Python code上場了
1 | from ctypes import cdll |
Windows版跟Linux版大同小異,最大的差別在於Windows可以寫 ./libfoo
而不用寫 ./libfoo.dll
:而 Linux沒有附檔名的話會發生錯誤。
當然,swig跟Boost Python一樣可以幫忙完成這件事。
How to call Python code from C code
在Mint 15下測試,Python版本2.7.3。以下的操作步驟跟Python相關,有需要的話需要修改。
首先,先安裝python-dev
。
1 | $ apt-get install python-dev |
測試的Python code cal.py
1 | def mix(a, b) : |
C語言本體:
1 | #include "Python.h" |
編譯他
1 | $ g++ pythontest.cpp -o pythontest -I/usr/include/python2.7 -lpython2.7 |
其中值得注意的是PyRun_SimpleString ("import sys; sys.path.insert(0, '.')");
這行。這樣的話他才會在目前目錄下找cal.py
這個檔案,不然會尋找/usr/lib/python2.7
這個目錄。找不到會Segmentation fault。
cal.py會先被編譯成cal.pyc,之後只需要這檔案即可。
而在Visual Studio使用的時候,要注意以下情況
- 假設你是用x86版的Python,只能使用Win32版的Setting,不然就只能使用x64版。
- 在Windows下需要
PyRun_SimpleString ("import sys; sys.path.insert(0, '.')");
即可找到目錄下的cal.py。當然,放到Python27\Lib
也是可以。
如果要讓事情變得更簡單,SWIG或是Boost.Python都是不錯的解決方案。
參考文章
The Language ⇔ Language Matrix
同樣是在網路上看到的
The Language ⇔ Language Matrix
可以看到很多程式語言互轉的解決方案,這年頭已經不是一個語言能解決所有問題的年代了。