1

いくつかのクラスを DLL で Luabind にエクスポートしましたが、これら 2 つのクラス (LuaScriptManager、EventManager) はすべて正常に動作しています。Lua から関数を呼び出すことができ、すべて問題ありませんが、DLL とリンクするクライアント実行可能ファイルに新しいクラスをセットアップしようとしていますが、これまでのところまったくうまくいきません。

呼び出す関数ごとに表示されるエラー メッセージは次のとおりです。「一致するオーバーロードが見つかりません。候補: void loadResource(ResourceManager&, std::string const&)」

クラス バインディングはhttp://www.nuclex.org/articles/5-cxx/1-quick-introduction-to-luabindからのものです。

struct Manager {
Manager() :
m_ResourceCount(0) {}

void loadResource(const std::string &sFilename) {
++m_ResourceCount;
}
size_t getResourceCount() const {
return m_ResourceCount;
}

size_t m_ResourceCount;
};
static Manager MyResourceManager;

void Bind(lua_State* l)
{
    // Export our class with LuaBind
    luabind::module(l) [
    luabind::class_<Manager>("ResourceManager")
    .def("loadResource", &Manager::loadResource)
    .property("ResourceCount", &Manager::getResourceCount)
    ];

    luabind::globals(l)["MyResourceManager"] = &MyResourceManager;
}

対応する lua テスト コードは次のとおりです。

-- The following call will fail with the above error
MyResourceManager:loadResource("abc.res")
--MyResourceManager:loadResource("xyz.res")

-- If the function is commented out, this will work (accessing the property)
ResourceCount = MyResourceManager.ResourceCount

-- Calling my other classes' functions work fine
LuaScriptManager.GetInstance():WriteLine(ResourceCount)

この奇妙な動作の原因は何ですか?

4

1 に答える 1

5

これは、私が Luabind メーリング リストに送ったメールのコピーです。 http://sourceforge.net/mailarchive/message.php?msg_id=27420879

これが Windows と DLL にも当てはまるかどうかはわかりませんが、GCC と Linux の共有モジュールで同様の経験がありました: Luabind に登録されたクラスはその共有ライブラリ内でのみ有効ですが、共有ライブラリの境界を越えて使用するとセグメンテーション違反が発生します.

解決策は、luabind::type_id クラスにパッチを適用し、typeid(T)::operator= の代わりに typeid(T).name() を使用して比較することでした。GCC の場合、typeid 演算子が共有ライブラリ間で機能しない理由については、こちら [1] で説明されています。この特定のケースでは、Lua の require() を使用して共有ライブラリをロードしましたが、残念ながら、これは RTLD_GLOBAL を dlopen に渡しません。

[1] http://gcc.gnu.org/faq.html#dso

typeid の等価性の問題は、他の C++ ライブラリ (boost::any [2] など) にも現れており、同じ修正 [3]、typeid(T).name() の比較が行われています。

[2] https://svn.boost.org/trac/boost/ticket/754
[3] https://svn.boost.org/trac/boost/changeset/56168

付属のパッチが DLL の場合にも役立つかもしれません。

--- include.orig/luabind/typeid.hpp
+++ include/luabind/typeid.hpp
@@ -6,6 +6,7 @@
 # define LUABIND_TYPEID_081227_HPP

 # include <boost/operators.hpp>
+# include <cstring>
 # include <typeinfo>
 # include <luabind/detail/primitives.hpp>

@@ -33,17 +34,17 @@

     bool operator!=(type_id const& other) const
     {
-        return *id != *other.id;
+        return std::strcmp(id->name(), other.id->name()) != 0;
     }

     bool operator==(type_id const& other) const
     {
-        return *id == *other.id;
+        return std::strcmp(id->name(), other.id->name()) == 0;
     }

     bool operator<(type_id const& other) const
     {
-        return id->before(*other.id);
+        return std::strcmp(id->name(), other.id->name()) < 0;
     }

     char const* name() const
于 2011-04-28T21:35:50.793 に答える