【问题标题】:Embedded Lua Singleton Pattern Linux vs Mingw嵌入式 Lua 单例模式 Linux 与 Mingw
【发布时间】:2021-06-02 14:01:12
【问题描述】:

我正在开发一个嵌入式 Lua 项目,并注意到如果我使用的是本机 Linux 编译器与 MinGw-w64 交叉编译器,行为会有所不同。我使用 Swig 生成包装文件,使用 CMake 构建项目(并使用 Wine 进行测试)。

节点.h

#ifndef NODE_H
#define NODE_H

class Node {
public:
  static Node* GetRoot();
  int GetCount();
  void SetCount(int count);
private:
  static Node *root;
  int count;
};

#endif /* NODE_H */

node.cpp

#include "node.h"

Node* Node::GetRoot() {
  return root;
}

int Node::GetCount() {
  return count;
}

void Node::SetCount(int count) {
  this->count = count;
}

Node* Node::root = {new Node()};

node.i

%module node

%{
  #include "node.h"
%}

%include "node.h"

main.cpp

#include <iostream>

#include "node.h"

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"  
}
extern "C" int luaopen_node(lua_State* L);

int main() {
  lua_State *L = luaL_newstate();
  luaL_openlibs(L);
  luaopen_node(L);

  luaL_loadfile(L, "main.lua");
  lua_call(L, 0, 0);
  lua_getglobal(L, "init");
  lua_call(L, 0, 0);

  std::cout << Node::GetRoot()->GetCount() << std::endl;
}

CMakeLists.txt


cmake_minimum_required(VERSION 3.13)
project(Singleton)

find_package(Lua REQUIRED)

add_executable(singleton main.cpp)
target_link_libraries(singleton nodelib)
target_link_libraries(singleton nodelua)
target_link_libraries(singleton ${LUA_LIBRARIES})

add_library(nodelib SHARED)
target_sources(nodelib PUBLIC
  node.h
  node.cpp)

find_package(SWIG REQUIRED)
include(UseSWIG)
set_property(SOURCE node.i PROPERTY CPLUSPLUS ON)

swig_add_library(nodelua
  TYPE SHARED
  LANGUAGE lua
  SOURCES node.i)
target_include_directories(nodelua PRIVATE "${PROJECT_SOURCE_DIR}")
swig_link_libraries(nodelua
  PRIVATE
  nodelib
  ${LUA_LIBRARIES})

main.lua

function init()
   local root = node.Node.GetRoot()
   root:SetCount(1)
end

谁能解释为什么本机编译时输出为1,而与MinGw 交叉编译时输出为0?从嵌入式 Lua 调用返回时,如何让单例正确更新?

【问题讨论】:

    标签: c++ cmake lua mingw swig


    【解决方案1】:

    对于后代来说,问题在于 DLL 不能很好地处理这样的静态成员。由于singleton 可执行文件和nodelua 库都依赖于nodelib,因此它们都获得了在其头文件中声明的静态成员的自己的副本。通过在node.cpp 文件中将root 设为静态全局来解决此问题。 (也让nodelua成为静态库)

    【讨论】:

      猜你喜欢
      • 2010-10-21
      • 1970-01-01
      • 2011-05-30
      • 2012-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多