Swig和Lua:如何将Lua文件映射到*

Swig和Lua:如何将Lua文件映射到*,lua,swig,Lua,Swig,我有一个C函数,它接受FILE*作为参数,我想在Lua中使用这个函数,传递Lua文件。我想我需要一个%typemap来做这个。怎么写? (我刚开始学习Lua)。您正在使用SWIG为您的C代码生成Lua绑定?为什么不直接使用LuaC+API,或者如果你可以使用C++,Luabind?我认为这两种方法中的任何一种都比尝试使用SWIG要好,除非你已经对SWIG有了强烈的依恋。要做到你所要求的,没有简单的方法 Lua文件类接口抽象了底层实现。您不能简单地键入映射。但是,您可以创建一个封装所需文件操作的C

我有一个C函数,它接受
FILE*
作为参数,我想在Lua中使用这个函数,传递Lua文件。我想我需要一个
%typemap
来做这个。怎么写?
(我刚开始学习Lua)。

您正在使用SWIG为您的C代码生成Lua绑定?为什么不直接使用LuaC+API,或者如果你可以使用C++,Luabind?我认为这两种方法中的任何一种都比尝试使用SWIG要好,除非你已经对SWIG有了强烈的依恋。

要做到你所要求的,没有简单的方法

Lua文件类接口抽象了底层实现。您不能简单地键入映射。但是,您可以创建一个封装所需文件操作的C代理,并使用SWIG在Lua中创建此代理的实例。然后,您可以生成一个typemap,将文件*转换为包装器代理实例

比如:

class MyFileProxy {
    private:
        FILE* fp;
    public:
        MyFileProxy(FILE* fp);
        MyFileProxy(const char* path); 

        FILE* GetFilePointer();

        Seek(...
在SWIG中,绑定只是:

%module "MyFile"

%{
#include "MyFileProxy.h"
%}

// Tell SWIG how to use a proxy for functions that take a FILE*
%typemap(in) FILE*
{
    void* tmp = 0;
    SWIG_ConvertPtr(L,$argnum,(void**)&tmp,$1_descriptor,1);

    if (tmp)
    {
        MyFileProxy* proxy = (MyFileProxy)tmp;
        arg$argnum = proxy->GetFilePointer();
    }
}

// Tell SWIG how to create a proxy when returning FILE*
%typemap(out) FILE*
{
    MyFileProxy* pResult = new MyFileProxy($arg);
    SWIG_NewPointerObj(L, pResult, $1_descriptor, 1);
}

%include "MyFileProxy.h 

}

但是,您将无法直接使用io:File

这是我最后想出的解决方案

在Lua source的liolib.c中,有一个函数
FILE*tofile(Lua_State*L)
,它将Lua文件转换为c文件*,但它不是API的一部分。我对其进行了一些修改,以制作一个类型图:

%typemap(in) FILE * {
    FILE **f;
    if (lua_isnil(L, $input))
        $1=NULL;
    else {
        f = (FILE **)luaL_checkudata(L, $input, "FILE*");
        if (*f == NULL)
            luaL_error(L, "attempt to use a closed file");
        $1=*f;
    }
}

这个类型映射也接受nil,因为我需要一种方法将NULL传递给C函数。

我正在使用SWIG生成Python绑定,所以我认为最简单的方法是将相同的.I文件重新用于Lua绑定。除了问题中描述的例外,它工作正常。感谢您指出其他选项。这是一个很好的发现。谢谢分享!