Edited at

cocos2d-xで"socket.url"をrequireできない

More than 1 year has passed since last update.


Environment


  • cocos2d-x 3.14.1

  • macOS Sierra 10.12.1


Problem

デフォルトで入っているはずの"socket.url"を読み込もうとすると、

以下のようにnot foundとなり、requireできない

can not get file data of /usr/local/share/lua/5.1/?/init.luasocket/socket.lua

[LUA-print] [string "-----------------------------------------------------------------------------..."]:13: module 'socket.socket' not found:
no field package.preload['socket.socket']
no file './socket/socket.lua'
no file '/usr/local/share/luajit-2.1.0-beta2/socket/socket.lua'
no file '/usr/local/share/lua/5.1/socket/socket.lua'
no file '/usr/local/share/lua/5.1/socket/socket/init.lua'
no file './socket/socket.so'
no file '/usr/local/lib/lua/5.1/socket/socket.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
no file './socket.so'
no file '/usr/local/lib/lua/5.1/socket.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
以下略


Solution

cocos2d_lua_bindingsプロジェクトの

luaopen_luasocket_scripts.cを見てみればわかるが、

はっきりと"socket.url"はpackageのpreloadに入っている

static luaL_Reg luasocket_scripts_modules[] = {

{"ltn12", luaopen_lua_m_ltn12},
{"mime", luaopen_lua_m_mime},
{"socket.ftp", luaopen_lua_m_socket_ftp},
{"socket.headers", luaopen_lua_m_socket_headers},
{"socket.http", luaopen_lua_m_socket_http},
{"socket.mbox", luaopen_lua_m_socket_mbox},
{"socket.smtp", luaopen_lua_m_socket_smtp},
{"socket.tp", luaopen_lua_m_socket_tp},
{"socket.url", luaopen_lua_m_socket_url},
{"socket", luaopen_lua_m_socket},
{NULL, NULL}
};

void luaopen_luasocket_scripts(lua_State* L)
{
luaL_Reg* lib = luasocket_scripts_modules;
lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
for (; lib->func; lib++)
{
lib->func(L);
lua_setfield(L, -2, lib->name);
}
lua_pop(L, 2);
}

じゃあ何が問題かというと、luaopen_lua_m_socket_urlのloadしているscriptが問題になっている。

そのため、おそらくpreloadのfunctionを実行しようとした際に、エラーが発生して、読み込み失敗になっているのだと思う。

以下はloadしているscriptだが、socketのrequireを"socket"ではなく、"socket.socket"と記述されている

/* socket.url */

static const char *lua_m_socket_url =
"-----------------------------------------------------------------------------\n"
"-- URI parsing, composition and relative URL resolution\n"
"-- LuaSocket toolkit.\n"
"-- Author: Diego Nehab\n"
"-----------------------------------------------------------------------------\n"
"\n"
"-----------------------------------------------------------------------------\n"
"-- Declare module\n"
"-----------------------------------------------------------------------------\n"
"local string = require(\"string\")\n"
"local base = _G\n"
"local table = require(\"table\")\n"
"local socket = require(\"socket.socket\")\n"
"\n"
以下略

なるほど、そりゃ動かんわなw

scriptを修正するにしても、他のscriptもこのように記述されているので、簡単に"socket.socket"を追加する対処法をとった

luasocket_scripts.cのluasocket_scripts_modulesを以下のように修正すれば、正常に動くようになった

static luaL_Reg luasocket_scripts_modules[] = {

{"ltn12", luaopen_lua_m_ltn12},
{"mime", luaopen_lua_m_mime},
{"socket.ftp", luaopen_lua_m_socket_ftp},
{"socket.headers", luaopen_lua_m_socket_headers},
{"socket.http", luaopen_lua_m_socket_http},
{"socket.mbox", luaopen_lua_m_socket_mbox},
{"socket.smtp", luaopen_lua_m_socket_smtp},
{"socket.tp", luaopen_lua_m_socket_tp},
{"socket.url", luaopen_lua_m_socket_url},
{"socket.socket", luaopen_lua_m_socket},
{"socket", luaopen_lua_m_socket},
{NULL, NULL}
};


追記

修正した後で気づいたけど、external以下全部ignoreされてるやつだったww

ということで上記の解決法はちょっと良くない(ほんと良くない)ので別の解決法考えます


追記

とりあえずすっごーくダサいけど、cocosの中の人じゃないと直せないとこ(根本解決ができないのが悔しい!)なので、

以下のようにして問題のモジュールをrequireする直前に

"socket.socket"モジュールをpreloadに追加して修正した

-- fix problem of couldn't include "socket.url" and more

package.preload["socket.socket"] = package.preload["socket"]

local socket = require("socket")
socket.url = require("socket.url")