最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++與Lua交互內(nèi)存分配詳解

 更新時間:2023年11月17日 10:29:14   作者:江澎涌  
C/C++ 與 Lua 的交互是通過 lua_State 這一句柄進(jìn)行交互,我們常規(guī)的創(chuàng)建都是通過 luaL_newstate 這一輔助函數(shù),這篇文章主要給大家詳細(xì)介紹了C++與Lua交互內(nèi)存分配,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下

一、lua_State 創(chuàng)建

C/C++ 與 Lua 的交互是通過 lua_State 這一句柄進(jìn)行交互。我們常規(guī)的創(chuàng)建都是通過 luaL_newstate 這一輔助函數(shù),他的源碼實現(xiàn)如下:

LUALIB_API lua_State *luaL_newstate (void) {
  lua_State *L = lua_newstate(l_alloc, NULL);
  if (l_likely(L)) {
    lua_atpanic(L, &panic);
    lua_setwarnf(L, warnfoff, L);  /* default is warnings off */
  }
  return L;
}

通過源碼可以知道,真正的創(chuàng)建是通過 lua_newstate 函數(shù)

LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud)

描述

函數(shù)創(chuàng)建并返回 lua_State 類型的指針,后續(xù)通過這一指針和 Lua 進(jìn)行交互。這期間所有的內(nèi)存分配和釋放都會由參數(shù) f 函數(shù)進(jìn)行完成,包括該函數(shù)返回的 lua_State 。

參數(shù)

  • 參數(shù) f :分配函數(shù)
  • 參數(shù) ud :自定義用戶數(shù)據(jù),會攜帶進(jìn)入 f 函數(shù)

返回值:

lua_State 的指針

二、分配函數(shù)

Lua 中默認(rèn)的分配函數(shù)使用了 C 語言標(biāo)準(zhǔn)函數(shù)庫的標(biāo)準(zhǔn)函數(shù) malloc-realloc-free 進(jìn)行內(nèi)存的管理,以下便是 Lua 默認(rèn)分配函數(shù)。

static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
  (void)ud; (void)osize;  /* not used */
  if (nsize == 0) {
    free(ptr);
    return NULL;
  }
  else
    return realloc(ptr, nsize);
}

我們可以自行定義,只需遵循 lua_Alloc 格式,通過 lua_newstate 函數(shù)或 lua_setallocf 函數(shù)設(shè)置即可生效

typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);

參數(shù):

  • 參數(shù) ud: lua_newstate 的第二個參數(shù)便會作為該參數(shù),并且是每次調(diào)用該分配函數(shù)都會攜帶。
  • 參數(shù) ptr: 正要被分配、或是重新分配、或者是要被釋放的塊地址。
  • 參數(shù) osize: 原始塊的大小。
  • 參數(shù) nsize: 需要申請的塊大小。

返回值:

  • 如果需要創(chuàng)建新的內(nèi)存塊,則將創(chuàng)建的內(nèi)存塊指針返回。
  • 如果不需要創(chuàng)建內(nèi)存塊,則返回 NULL。

值得注意:

從分配函數(shù)的參數(shù)和返回值,已經(jīng)知道了這一函數(shù)的職責(zé):釋放原始塊和創(chuàng)建新的塊并返回。所以會涉及以下一些小細(xì)節(jié):

  • 當(dāng) ptr 是 NULL ,則原始內(nèi)存塊大小肯定是零,所以 Lua 使用 osize 存放某些調(diào)試信息。
  • 當(dāng) ptr 是 NULL ,則分配函數(shù)必須分配并返回 nsize 指定大小的塊。如果無法分配相應(yīng)的塊,則返回 NULL 。如果此時 nsize 為 零 則返回 NULL 。
  • 當(dāng) nsize 為零時,分配函數(shù)必須釋放 ptr 指向的塊并返回 NULL 。
  • 如果 ptr 不是 NULL 并且 nsize 不為零,則可以使用 realloc 進(jìn)行重新分配塊并返回(地址可能和原來一樣,也可能不一樣)。和第二點一樣,如果出錯了則返回 NULL 。
  • Lua 會假定分配函數(shù)在塊的新尺寸( nsize )小于或等于舊尺寸( osize )時不會失敗。

三、獲取當(dāng)前的內(nèi)存分配函數(shù)

通過 lua_getallocf 獲取 Lua State 當(dāng)前的內(nèi)存分配函數(shù)

LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);

參數(shù):

  • 參數(shù) L: lua_State 指針。
  • 參數(shù) ud: 會把當(dāng)前設(shè)置的自定義用戶數(shù)據(jù)設(shè)置給這一參數(shù)。

返回值:

Lua 當(dāng)前使用的內(nèi)存分配函數(shù)

四、設(shè)置內(nèi)存分配函數(shù)

通過 lua_setallocf 設(shè)置新的內(nèi)存分配函數(shù)

LUA_API void      (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);

參數(shù):

  • 參數(shù) L: lua_State 指針。
  • 參數(shù) f: 需要設(shè)置新的內(nèi)存分配函數(shù)。
  • 參數(shù) ud: 自定義用戶數(shù)據(jù)。

五、舉個例子

下面的代碼主要驗證了三個步驟:

  • 創(chuàng)建 lua_State 時傳入自己的內(nèi)存分配函數(shù)和自定義用戶數(shù)據(jù),函數(shù)中會打印所有的參數(shù)。
  • 獲取當(dāng)前的分配函數(shù)。
  • 替換當(dāng)前的分配函數(shù),最后關(guān)閉 lua_State 的時候會打印日志。
static void *alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
    const char *udContent = *(const char **) ud;
    std::cout << "ud: " << udContent << "; *ptr: " << ptr << "; osize: " << osize << "; nsize: " << nsize << std::endl;
    if (nsize == 0) {
        free(ptr);
        return nullptr;
    } else
        return realloc(ptr, nsize);
}

static void *newalloc(void *ud, void *ptr, size_t osize, size_t nsize) {
    const char *udContent = *(const char **) ud;
    std::cout << "新的分配函數(shù) " << "ud: " << udContent << "; *ptr: " << ptr << "; osize: " << osize << "; nsize: " << nsize << std::endl;
    if (nsize == 0) {
        free(ptr);
        return nullptr;
    } else
        return realloc(ptr, nsize);
}

void allocationFunction() {
    // 常規(guī)的創(chuàng)建 lua_State
//    auto L = luaL_newstate();

    printf("------------- 自定義內(nèi)存分配函數(shù) -------------\n");
    // 自定義內(nèi)存分配數(shù)據(jù)
    auto ud = "ud test message.";
    auto L = lua_newstate(alloc, &ud);

    printf("------------- 獲取 Lua 當(dāng)前的內(nèi)存分配函數(shù) -------------\n");
    // lua_getallocf 第二個參數(shù)會返回之前設(shè)置的 自定義內(nèi)存分配數(shù)據(jù)
    void *userData = nullptr;
    lua_Alloc allocFunc = lua_getallocf(L, &userData);
    const char *udContent = *(const char **) userData;
    std::cout << &allocFunc << " " << udContent << std::endl;

    printf("------------- 設(shè)置 Lua 的內(nèi)存分配函數(shù) -------------\n");
    auto nud = "new ud test message.";
    lua_setallocf(L, newalloc, &nud);

    std::cout << "關(guān)閉 lua_State " << std::endl;
    lua_close(L);
}

運行之后的日志

------------- 自定義內(nèi)存分配函數(shù) -------------
ud: ud test message.; *ptr: 0x0; osize: 8; nsize: 1624
...... 省略很多內(nèi)存分配打印日志
ud: ud test message.; *ptr: 0x0; osize: 4; nsize: 30
------------- 獲取 Lua 當(dāng)前的內(nèi)存分配函數(shù) -------------
0x7ff7b7775f80 ud test message.
------------- 設(shè)置 Lua 的內(nèi)存分配函數(shù) -------------
關(guān)閉 lua_State 
新的分配函數(shù) ud: new ud test message.; *ptr: 0x0; osize: 0; nsize: 0
...... 省略很多內(nèi)存分配打印日志
新的分配函數(shù) ud: new ud test message.; *ptr: 0x7fd3ef80c400; osize: 1624; nsize: 0

以上就是C++與Lua交互內(nèi)存分配詳解的詳細(xì)內(nèi)容,更多關(guān)于C++與Lua交互內(nèi)存分配的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 全局變量與局部變量在內(nèi)存中的區(qū)別詳細(xì)解析

    全局變量與局部變量在內(nèi)存中的區(qū)別詳細(xì)解析

    以下是對全局變量與局部變量在內(nèi)存中的區(qū)別進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2013-10-10
  • C++深入探索類真正的形態(tài)之struct與class

    C++深入探索類真正的形態(tài)之struct與class

    前邊我們所定義的類,均是使用struct關(guān)鍵字來定義,但是C++中真正用于定義類的關(guān)鍵字為class,因為要C++兼容C,所以保留struct關(guān)鍵字,struct與class的用法完全相同
    2022-04-04
  • C語言16進(jìn)制與ASCII字符相互轉(zhuǎn)換

    C語言16進(jìn)制與ASCII字符相互轉(zhuǎn)換

    大家好,本篇文章主要講的是C語言16進(jìn)制與ASCII字符相互轉(zhuǎn)換,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C++輸出上三角/下三角/菱形/楊輝三角形(實現(xiàn)代碼)

    C++輸出上三角/下三角/菱形/楊輝三角形(實現(xiàn)代碼)

    本篇文章是對C++中輸出上三角/下三角/菱形/楊輝三角形的示例代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • VC使用TerminateProcess結(jié)束進(jìn)程實例

    VC使用TerminateProcess結(jié)束進(jìn)程實例

    這篇文章主要介紹了VC使用TerminateProcess結(jié)束進(jìn)程的方法,實例演示了TerminateProcess結(jié)束進(jìn)程的具體實現(xiàn)過程,在進(jìn)行VC應(yīng)用程序開發(fā)時非常具有實用價值,需要的朋友可以參考下
    2014-10-10
  • 基于Matlab實現(xiàn)繪制3D足球的示例代碼

    基于Matlab實現(xiàn)繪制3D足球的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Matlab實現(xiàn)繪制3D足球,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Matlab有一定幫助,需要的可以參考一下
    2022-11-11
  • C語言棧之順序棧

    C語言棧之順序棧

    這篇文章主要為大家詳細(xì)介紹了C語言的順序棧,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • vscode?采用C++17版本進(jìn)行編譯的實現(xiàn)

    vscode?采用C++17版本進(jìn)行編譯的實現(xiàn)

    本文主要介紹了vscode?采用C++17版本進(jìn)行編譯,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 常用Hash算法(C語言的簡單實現(xiàn))

    常用Hash算法(C語言的簡單實現(xiàn))

    下面小編就為大家?guī)硪黄S肏ash算法(C語言的簡單實現(xiàn))。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • C和C++11之enum枚舉的具體使用方法

    C和C++11之enum枚舉的具體使用方法

    這篇文章主要介紹了C和C++11之enum枚舉的具體使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12

最新評論

班玛县| 广灵县| 全椒县| 连江县| 桂阳县| 湘潭县| 璧山县| 宾川县| 边坝县| 巴中市| 营山县| 茂名市| 开封市| 阳曲县| 宣武区| 两当县| 平遥县| 敦煌市| 汕尾市| 霍山县| 肥乡县| 岳普湖县| 屯留县| 石阡县| 海丰县| 嵊泗县| 东光县| 璧山县| 辽宁省| 兴国县| 即墨市| 韩城市| 镇雄县| 晋宁县| 镶黄旗| 淮滨县| 岳西县| 忻城县| 庆元县| 绥宁县| 绥江县|