轉載自:http://www.cnblogs.com/think/archive/2011/10/06/2199695.htmlhtml
CEF的C API是由libcef DLL暴露的基於C的接口,cef_capi.h 頭文件中定義的接口是由CEF translator tool自動生成的C++ API鏡像。api
理解引用計數多是使用CEF C API最困難的部分了,CEF使用引用計數概念相似於COM的概念,這裏有一些基本的規則能夠幫助你減小使用引用計數時的困難。app
1. 當將一個結構傳給它本身的成員函數時,不要進行引用計數的加、減操做:函數
struct->call_func(struct,...); // no reference counting change on 'struct'
2. 在將結構做爲參數傳給其它結構前,增長引用計數:this
// Should have already added a reference to 'some_other_struct' struct->call_func(...,some_other_struct,...);
3. 在你使用完從別處以參數傳過來的結構後,減小它的引用計數:線程
void my_func(...,some_other_struct,...) { // remove a reference from 'some_other_struct' after you're done using it }
4. 在傳入一個處理程序前,增長它的引用,好比,cef_create_browser(),當API再也不須要使用某一處理程序時,會移除它的引用。指針
5. 使用原子的引用計數實現,由於add_ref和release可能會跨線程調用,WinAPI InterlockedIncrement() 和 InterlockedDecrement() 函數可用於此目的。htm
6. 若是引用計算變成0,處理程序應該在已賦值給結構的releae()回調函數中刪除本身:blog
// custom data structure that extends cef_handler_t接口
typedef struct _my_handler_t {
cef_handler_t handler; // cef_handler_t member comes first
// custom members here, including the reference count variable
} my_handler_t;
// allocate the custom data structure (already initialized to zero)
my_handler_t* my_handler = (my_handler_t*)calloc(1, sizeof(my_handler_t));
// set the size member of cef_base_t appropriately
my_handler->handler.base.size = sizeof(cef_handler_t);
// assign the release callback function (and the other callback functions)
my_handler->handler.base = my_release;
...
// release callback function implementation for my_handler_t
int CEF_CALLBACK my_release(struct _cef_base_t* base) {
// this cast works because cef_base_t is the first member of
// cef_handler_t and cef_handler_t is the first member of my_handler_t
my_handler_t* my_handler = (my_handler_t*)base;
// decrement the reference count (stored as a custom member of my_handler_t)
// free the my_handler_t structure when the reference count reaches zero
if(reference_count_is_zero)
free(my_handler);
}
7. 清除代碼添加給結構的全部附加的引用(好比,在處理程序實現中保持cef_broswer_t指針的引用),最終的釋放引用的機會是cef_handler_t::handle_before_window_closed()。
8. 若是沒有任何的crash產生,在shutdown時也會命中DebugObjCt斷言,那麼就說明你正確的處理了引用計數。