2015-09-27 39 views
0

我想將不透明的數據緩衝區從C傳遞給Lua,而不實際複製所有數據(因爲它可能是非常大的100 MB的MB或GB)。將只讀緩衝區從C傳遞給Lua

更具體地說,我有一個C段,看起來像這樣:

uint8_t *buffer = // points to some memory 
size_t size = // size of the buffer 

我的C程序不知道在緩衝區中的數據結構。它完全無視它。除了調用負責使用這些數據的Lua函數之外,它絕對不會觸及這些數據。

我的目標是將此緩衝區傳遞給Lua,然後Lua將解釋數據的內容並基於此執行各種操作(Lua代碼知道如何根據其內容確定數據的結構或尺寸)。此外,Lua代碼不會修改緩衝區(只能從中讀取)。

下面是我理想中的功能的一些示例僞代碼:

bool perform_action(lua_State *L, uint8_t *buffer, size_t size) { 

    // Pass buffer to lua 
    // call "process_buffer" function (written in Lua) 
    // get return from "process_buffer" function (a boolean) 
    // free(buffer); 
    // return the result above 
} 

這個問題,我想,是關係到:lua newbie : C-Lua How to pass a struct/buffer to lua from C?。但是,該線程中的解決方案是:「使用LuaJIT」,這對我沒有任何意義。

一個潛在的解決方案是使用:

lua_pushlstring (L, buffer, size); 

,但不會這使得數據的副本?有沒有辦法做到零拷貝(因爲數據非常大)?

任何幫助,將不勝感激。謝謝!

+0

爲什麼不簡單地寫這個函數到Lua read_part_of_buffer(start_offset,length,return_this_part_as_number_instead_of_string)? –

回答

1

正如您已經注意到的那樣,lua_pushlstring是將原始數據以字符串形式推送到Lua的常用方法。爲了避免複製,你需要將一個弱指針推向Lua,這會導致你到userdata。但如何重新解釋這個用戶數據在Lua作爲一個字符串?短:你不能!使用LuaJIT您可以將用戶數據強制轉換爲CData指針(您的用戶數據將是一個可以保存緩衝區+大小的結構) - easy & direct。沒有,你必須複製通過添加metatable到你的userdata,它允許提取作爲字符串和請求大小的塊。

1

最好的辦法是創建一個userdata,其中包含一個指向緩衝區及其大小的指針,並實現一個允許抓取單個字節並將其推送到lua的元方法。

根據您的lua腳本的詳細信息,此用戶數據可以用作腳本使用的字符串類型的嵌入式替換,或者您可能必須實現更多元方法,如__len等。

如果您的腳本確實要求數據由字符串表示,那麼您最有可能是SOL。 Lua需要自行管理字符串中的數據,因此如果您希望它完全表示爲腳本中的字符串類型,則必須將其複製到lua擁有的緩衝區中。

爲了確保您的需要,您必須發佈您的代碼。