无法将 Lua 编译为 C++

如何解决无法将 Lua 编译为 C++

我正在尝试使用以下 CMakeLists.txt(和 CMake 3.21)构建 Lua 5.4.3(撰写本文时的最新版本)(忽略目标被称为 data = [[value] for value in lst] safelist = spark.createDataFrame(data=data,schema=["meta_info"]) filtered = df.join(safelist,on='meta_info') filtered.show() 的事实,尽管它是共享库):

import pyspark.sql.functions as F
blst = sc.broadcast(lst)
df.filter(F.col("meta_info").isin(blst.value)).show()

在使用 MSVC 构建时,lua_static 已定义,因此我假设到目前为止一切都按预期工作。然后安装后,我像这样链接到库

cmake_minimum_required(VERSION 3.16)

project(Lua LANGUAGES CXX)

# make cache variables for install destinations
include(GNUInstallDirs)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

set(LUA_LIB_SRCS 
    "src/ldblib.c"
    "src/ldebug.c"
    "src/ldo.c"
    "src/ldump.c"
    "src/lfunc.c"
    "src/lgc.c"
    "src/linit.c"
    "src/liolib.c"
    "src/lopcodes.c"
    "src/llex.c"
    "src/lmathlib.c"
    "src/lmem.c"
    "src/loadlib.c"
    "src/lobject.c"
    "src/loslib.c"
    "src/lparser.c"
    "src/lstate.c"
    "src/lstring.c"
    "src/lstrlib.c"
    "src/ltable.c"
    "src/ltablib.c"
    "src/ltm.c"
    "src/lundump.c"
    "src/lutf8lib.c"
    "src/lvm.c"
    "src/lzio.c"
    "src/lapi.c"
    "src/lauxlib.c"
    "src/lbaselib.c"
    "src/lcode.c"
    "src/lcorolib.c"
    "src/lctype.c"
)

set(LUA_HEADERS_INSTALL
    "src/lua.h"
    "src/luaconf.h"
    "src/lualib.h"
    "src/lauxlib.h"
    "src/lua.hpp"
)

# Compile directly as C++.
set_source_files_properties(${LUA_LIB_SRCS} PROPERTIES LANGUAGE CXX )

add_library(lua_static SHARED ${LUA_LIB_SRCS})
set_target_properties(lua_static PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(lua_static PROPERTIES DEBUG_POSTFIX d)

# make sure __cplusplus is defined when using msvc
if (MSVC)
    target_compile_options(lua_static PRIVATE /TP       # /TP doesn't is somehow stripped or ignored?
                                       /Zc:__cplusplus)
endif ()

target_include_directories(lua_static
                           PUBLIC
                           "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)

install(TARGETS lua_static
        EXPORT lua_static_targets
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
        INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(FILES ${LUA_HEADERS_INSTALL} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(EXPORT lua_static_targets
        FILE LuaStaticTargets.cmake
        NAMESPACE lua::
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lua
)

include(CMakePackageConfigHelpers)

configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/LuaConfig.cmake"
  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lua
)

install(FILES
          "${CMAKE_CURRENT_BINARY_DIR}/LuaConfig.cmake"
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lua
)

我想把 Lua 编译成 C++ 的原因是为了启用异常(而不是 __cplusplus)。所以为了测试是否会抛出异常,我尝试在这个测试程序中调用一个

cmake_minimum_required(VERSION 3.16)
project(TestProject)

add_executable(Test Main.cpp)

# Lua
find_package(lua REQUIRED PATHS ${CMAKE_CURRENT_LIST_DIR}/lua)
set_target_properties(lua::lua_static PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(Test lua::lua_static)

当使用调试器进入 longjmp 时,我在某个时刻最终进入 ldo.c,其中 Visual Studio 指示 #include <lua.h> #include <lauxlib.h> #include <lualib.h> #include <iostream> constexpr char* Test_Lua = R"( function f (x,y) unknown() return 1/0 en )"; lua_State* state; int main(int argc,char* argv[]) { state = luaL_newstate(); luaL_openlibs(state); try { int error = luaL_loadbuffer(state,Test_Lua,strlen(Test_Lua),"Test"); lua_call(state,LUA_MULTRET); // Should thow,because of the syntax error } catch (...) { std::cout << "Exception!" << std::endl; goto end; } end: lua_close(state); return 0; } 不是通过 C++ 异常处理定义的。这是因为未定义 lua_call。跳转到我之前创建的 Lua 项目文件中的源文件,LUAI_THROW 已根据需要定义。我可以包含 Lua 头文件这一事实向我表明该库已被编译为 C++ 库。事实上,如果我尝试添加 __cplusplus,我会收到链接器错误。

有人能解释一下问题的原因吗?


编辑:

在深入研究这个问题后,我意识到所有编译都与 C++ 一样,是 Lua 在内部处理通过异常返回错误代码(例如 LUAI_THROW)的函数。这并不意味着我可以抓住并处理它们(我最初认为)。 extern "C" { ... } 之类的函数在不受保护的模式下运行,因此会调用恐慌函数(请参阅 @bremen_matt 的帖子)。

解决方法

我对 Lua 一无所知。那样的话...

我认为您缺少有关 Lua 内部工作方式的一些信息。如果我在第 57 行左右修改 ldo.c 中的宏以阅读:

#include <iostream>
#define LUAI_THROW(L,c) (fprintf(stderr,"THROWING\n"),throw(c))
#define LUAI_TRY(L,c,a) \
    try { a } catch(...) { fprintf(stderr,"CAUGHT\n"); if ((c)->status == 0) (c)->status = -1; }

然后当我运行这个时,我看到了输出:

THROWING
CAUGHT
PANIC: unprotected error in call to Lua API (attempt to call a string value)

这表明 Lua 在内部试图运行一段代码,捕获异常,然后退出而不抛出另一个异常。因此,您作为用户无法捕获此异常。它正在 Lua 内部使用。

只要快速浏览一下代码,就会发现您可能想要使用 lua_pcall。似乎 p 的意思是 protected?你可以用它做一些错误处理吗?无论哪种方式,该函数似乎也不会引发更高的错误。看来你必须传递一个函数来处理错误。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-