Lua C API Как определить, была ли функция вызвана как член класса или просто функция из таблицы?

У меня есть приложение C++, которое использует Lua C API. Я объявил глобальную таблицу через lua api:

lua_newtable(L);

lua_pushstring(L, "someLuaFunc");
lua_pushcfunction(L, &someCFunc);
lua_settable(L, -3);

lua_setglobal(L, "table1");

и теперь я могу вызвать someLuaFunc, используя '.' или ':'

table1.someLuaFunc()
table1:someLuaFunc()

и в обоих случаях запустится someCFunc.

Вопрос: есть ли способ внутри someCFunc определить, как он был вызван (через : или .)?

Проверка количества и типов аргументов в моем случае невозможна.


person xorza    schedule 14.12.2015    source источник
comment
Возможно, кто-то мог бы помочь в дальнейшем, если вы укажете, чего вы вообще пытаетесь достичь, то есть почему нет возможности проверить количество или типы аргументов, что было бы очевидным способом.   -  person Ctx    schedule 14.12.2015


Ответы (2)


Нет, ты не можешь.

object:method()

напрямую переводится на

main <123.lua:0,0> (4 instructions, 16 bytes at 00020510)
0+ params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0 functions
        1       [1]     GETGLOBAL       0 -1    ; object
        2       [1]     SELF            0 0 -2  ; "method"
        3       [1]     CALL            0 2 1

То есть опкод SELF выстраивает функцию рядом с вызывающим объектом на регистрах, а затем опкод CALL выполняет обычный вызов.

Парадигма Lua в этом случае — утиная типизация. В любом случае нет отдельного типа, просто таблица (или информация о пользователе), поэтому просто проверьте, есть ли в вашем аргументе необходимые данные/методы, которые вы хотите обработать/вызвать, и отклонить, если это не так.

person Oleg V. Volkov    schedule 14.12.2015
comment
Можно ли получить эти инструкции на чистом Lua? (Нравится GetInstructions(func)?) Если да, то как бы вы? - person warspyking; 14.12.2015
comment
@warspyking, да и нет. Вы можете использовать string.dump для получения дампа опкода, но его использование никак не поддерживается, кроме как loadstring вернуть его обратно, так что вы самостоятельно его анализируете. - person Oleg V. Volkov; 14.12.2015
comment
На самом деле, есть также библиотека инспектора байт-кода @lhf lbci (также доступно через LuaRocks). - person siffiejoe; 14.12.2015
comment
@Oleg Когда я распечатываю string.dump посимвольно, я не получаю инструкций, что мне не хватает? - person warspyking; 14.12.2015

Я, вероятно, не стал бы на это полагаться, но библиотека отладки Lua может это понять (путем поиска кода операции OP_SELF в байт-коде). В Луа:

local t = {}
function t:f()
  print( debug.getinfo( 1, "n" ).namewhat )
end

t.f( t ) --> prints "field"
t:f()    --> prints "method"

В C вам понадобятся lua_getstack() и lua_getinfo().

person siffiejoe    schedule 14.12.2015