zoukankan      html  css  js  c++  java
  • 为Lua5.3编写C模块简单示例

    为Lua5.3编写C模块简单示例

    一、编译安装Lua5.3

    MSVC 命令行安装脚本:

    @echo off
    md bin
    md lib
    md include
    cd src
    
    cl /c /nologo /W3 /O2 /Ob1 /Oi /Gs /MD /D_CRT_SECURE_NO_DEPRECATE l*.c
    ren lua.obj lua.o
    ren luac.obj luac.o
    lib /OUT:lua53.lib *.obj
    copy lua53.lib ..liblua53.lib
    del *.o *.obj *.exp *.lib *.dll *.exe
    
    cl /c /nologo /W3 /O2 /Ob1 /Oi /Gs /MD /D_CRT_SECURE_NO_DEPRECATE /DLUA_BUILD_AS_DLL l*.c
    ren lua.obj lua.o
    ren luac.obj luac.o
    link /DLL /IMPLIB:lua53.lib /OUT:lua53.dll *.obj
    link /OUT:lua53.exe lua.o lua53.lib
    link /OUT:luac53.exe luac.o *.obj
    copy lua53.exp ..inlua53.exp
    copy lua53.lib ..inlua53.lib
    copy lua53.dll ..inlua53.dll
    copy lua53.exe ..inlua53.exe
    copy luac53.exe ..inluac53.exe
    del *.o *.obj *.exp *.lib *.dll *.exe
    
    copy lauxlib.h ..includelauxlib.h
    copy lua.h ..includelua.h
    copy lua.hpp ..includelua.hpp
    copy luaconf.h ..includeluaconf.h
    copy lualib.h ..includelualib.h
    cd ..

    打开vs开发人员命令提示,执行此脚本,进行编译。

    生成的目录文件结构:

    使用VS编写Lua的C模块时, VS的配置。

     

    C模块mytest.h头文件源码:

    /* Start of mytest.h */
    
    #ifndef __MYTEST_H__
    #define  __MYTEST_H__
    
    #ifdef __unix__
    
    #define DllExport extern
    
    #else
    
    #define DllExport  __declspec( dllexport )
    
    #endif // __unix__
    
    #ifdef __cplusplus
    
    #include <lua.hpp>
    
    #else
    
    extern "C" {
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
    }
    
    #endif // __cplusplus
    
    
    #ifdef __cplusplus
    extern "C" { // 告诉编译器以C的方式编译, 防止变量名称及函数名称粉碎问题
    #endif // __cplusplus
    
    
    /* 此函数为C库中的“特殊函数", 在Windows系统中必须使用"__declspec( dllexport )"导出, 在类Unix上使用"extern"导出
     * 通过调用它注册所有C库中的函数,并将它们存储在适当的位置。
     * 此函数的命名规则应遵循:
     * 1、使用"luaopen_"作为前缀。
     * 2、前缀之后的名字将作为"require"的参数, 所以此名字必须和生成的dll同名否则找不到对应的库
     */
    DllExport int luaopen_cl01(lua_State* L);
    
    #ifdef __cplusplus
    } /* extern "C" */
    #endif // __cplusplus
    
    #endif // __MYTEST_H__
    
    /* End of mytest.h */

    C模块mytest.c文件源码:

    /* Start of mytest.c */
    
    #include <stdio.h>
    #include <math.h>
    #include <stdarg.h>
    #include <stdlib.h>
    
    #include "mytest.h"
    
    #ifdef __cplusplus
    extern "C" { // 告诉编译器以C的方式编译, 防止变量名称及函数名称粉碎问题
    #endif // __cplusplus
    
    /* 所有注册给Lua的C函数具有
     * "typedef int (*lua_CFunction) (lua_State *L);"的原型。
     */
    static int l_sin(lua_State *L)
    {   
        // 如果给定虚拟栈中索引处的元素可以转换为数字,则返回转换后的数字,否则报错。
        double d = luaL_checknumber(L, 1);
        lua_pushnumber(L, sin(d));  /* push result */
    
        /* 这里可以看出,C可以返回给Lua多个结果,
         * 通过多次调用lua_push*(),之后return返回结果的数量。
         */
        return 1;  /* number of results */
    }
    
    /* 需要一个"luaL_Reg"类型的结构体,其中每一个元素对应一个提供给Lua的函数。
     * 每一个元素中包含此函数在Lua中的名字,以及该函数在C库中的函数指针。
     * 最后一个元素为“哨兵元素”(两个"NULL"),用于告诉Lua没有其他的函数需要注册。
     */
    static const struct luaL_Reg cl01[] = {
        {"mysin", l_sin},
        {NULL, NULL}
    };
    
    /* 此函数为C库中的“特殊函数", 在Windows系统中必须使用"__declspec( dllexport )"导出, 在类Unix上使用"extern"导出
     * 通过调用它注册所有C库中的函数,并将它们存储在适当的位置。
     * 此函数的命名规则应遵循:
     * 1、使用"luaopen_"作为前缀。
     * 2、前缀之后的名字将作为"require"的参数, 所以此名字必须和生成的dll同名否则找不到对应的库
     */
    DllExport int luaopen_cl01(lua_State* L)
    {
        /* void luaL_newlib (lua_State *L, const luaL_Reg l[]);
         * 创建一个新的"table",并将"l"中所列出的函数注册为"table"的域。
         */ 
        luaL_newlib(L, cl01);
    
        return 1;
    }
    
    #ifdef __cplusplus
    } /* extern "C" */
    #endif // __cplusplus
    
    /* End of mytest.c */

    点击生成,产生以下文件

    我们只需要将 cl01.dll 文件,拷贝到Lua的工作目录下即可。

    LuaFile1.lua 文件源码:

    --region LuaFile1.lua
    --Date
    --此文件由[BabeLua]插件自动生成
    
    io.write(string.format("-------->>> %s <<<--------
    ", "testing ...")) -- 此函数不会自动换行
    local cl01lib = require("cl01")
    print("mysin(3.14 /2) result: ", cl01lib.mysin(3.14 /2))
    
    
    -- 通过调用控制台命令行使程序暂停
    -- os.execute("pause")
    
    --endregion

    运行结果现象:

  • 相关阅读:
    Creating a generic Web Parts for hosting ASP.NET User Controls
    Speed Up SQL Server Apps 提高SQL Server应用程序的运行效率 (Part 1)
    How to use CreateChildContorls method inherited from System.Web.UI.Control
    How to quickly access Web Part Management Page
    SQL Script tips for MS SQL Server
    How to enable single signon service on the SPS
    A brief summary of UML & Rational Rose – Use Case Diagram, Part II
    Borland Together for Visual Studio.Net V2.0 安装问题
    Speed Up SQL Server Apps 提高SQL Server应用程序的运行效率 (Part 2)
    体验ReSharper V1.0 for VS.Net 2003 Part I
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/7751724.html
Copyright © 2011-2022 走看看