LUA 스크립트에서 C ++ 함수를 어떻게 호출합니까?
-
06-07-2019 - |
문제
Visual Studio 2005를 사용하고 있습니다.
----------------------- [luapassing.cpp] ---------------------
#include "lua.h"
static int myCfunc (Lua_State *L){
double trouble = lua_tonumber(L,1);
lua_pushnumber(L,16.0 -trouble);
return 1;
}
int luaopen_luapassing (Lua_State *L){
static const lua_reg Map [] = {{"dothis",myCfunc},{NULL,NULL}};
luaL_register(L,"cstuff",Map);
return;
}
--------------------------- [CSAMPLE.LUA] ---------------------- -----
package.cpath = "./CLua2.dll"
require "luapassing"
print("hola")
print(seth.doThis(120))
해결책
몇 가지 문제가 있습니다. 나는 그것들을 설명하고, 당신 이이 샘플이 작동하도록 의도했다고 생각하는 것처럼 작동 해야하는 코드 조각을 제공 할 것입니다.
첫 번째 문제는 C ++ 컴파일러가 LUA에 중요한 DLL에서 내보낸 유일한 기능의 이름을 엉망이라는 것입니다. luaopen_luapassing()
. Windows의 스톡 바이너리 분포는 C 프로그램으로 컴파일되었으며 DLL 모듈 입력 지점의 C 스타일 이름을 가정합니다.
또한, 당신은에 대한 프로토콜이 있습니다 luaopen_x
약간 잘못 기능합니다. 이 함수는 Lua의 스택 상단에있는 항목 수를 Lua에서 사용할 수있는 값인지를 Lua에게 알려주는 정수를 반환합니다. 에 의해 가정 된 프로토콜 require
새 모듈의 테이블 개체를 스택 상단에두고 LUA로 반환하는 것을 선호합니다. 이를 위해 luaopen_x
기능은 일반적으로 사용됩니다 luaL_register()
당신이했던 것처럼, 그런 다음 1을 반환합니다.
이름 지정 문제도 있습니다. Pure Lua로 작성된 모듈은 이름을 잘 알 수있는 기회가 있습니다. 그러나 C로 작성된 모듈은 이름의 모듈 이름을 포함하는 DLL에서 함수를 내보내야합니다. 또한 그 모듈 이름을 제공해야합니다 luaL_register()
올바른 테이블이 글로벌 환경에서 생성되고 업데이트되도록합니다. 마지막으로 클라이언트 LUA 스크립트는로드 된 모듈이 전달 된 이름과 같은 글로벌 테이블에 표시됩니다. require
, 그것은 또한에서 반환됩니다 require
해당 스크립트의 로컬에 캐시 될 수 있습니다.
C 코드가있는 다른 몇 가지 NIT는 숫자 유형이 실제로 철자가되어야한다는 것입니다. lua_Number
이식성을 위해, 사용하는 것이 전통적 일 것입니다. luaL_checknumber()
보다는 lua_tonumber()
기능에 필요한 인수를 시행합니다. 개인적으로, 나는 LUA에 의해 공개적으로 알려진 이름과 관련된 이름과 관련된 공개 기능의 C 구현을 지명 할 것입니다. 그러나 그것은 맛의 문제 일뿐입니다.
이 버전의 C 측은 다음과 같은 문제를 해결해야합니다.
#include "lua.h"
static int my_dothis (Lua_State *L){
lua_Number trouble = luaL_checknumber(L,1);
lua_pushnumber(L,16.0 -trouble);
return 1;
}
extern "C" int luaopen_luapassing (Lua_State *L){
static const lua_reg Map [] = {
{"dothis", my_dothis},
{NULL,NULL}
};
luaL_register(L,"luapassing",Map);
return 1;
}
그런 다음 샘플 스크립트는로드 된 모듈을 적절한 이름으로, 해당 모듈에 의해 정의 된 기능을 적절한 이름으로 참조해야합니다. LUA는 사례에 민감하므로 모듈이 명명 된 함수를 작성하는 경우 dothis()
, 그런 다음 스크립트는 동일한 이름을 사용해야하며 이름을 찾을 수 없습니다. doThis()
, 예를 들어.
require "luapassing" print("hola") print(luapassing.dothis(120))
나는 실제로 위에서 컴파일하지 않고 실행하지 않았으므로 운동으로 오타 한두 명이 남을 수 있습니다 ;-)
다른 팁
LUA 바인딩에 대한 C ++를 많이 할 예정이라면 살펴 보겠습니다. Luabind.
C ++로 컴파일하고 'C'인터페이스와 일치하려면 외부 가시 기능을 다음과 같이 선언해야합니다. extern "C"
이름 관리를 피하기 위해.