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

时间:2009-11-21 00:52:52

标签: lua swig

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

3 个答案:

答案 0 :(得分:5)

这是我最终提出的解决方案。

在Lua源代码中,在liolib.c中,有一个函数FILE *tofile (lua_State *L),它将Lua文件转换为C FILE *,但它不是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;
    }
}

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

答案 1 :(得分:0)

您是否正在使用SWIG为您的C代码生成Lua绑定?为什么不直接使用Lua C API,或者如果你可以使用C ++,Luabind?我认为除了你已经对SWIG有很强的依恋之外,其中任何一个都比试图使用SWIG更好。

答案 2 :(得分:0)

没有简单的方法来做你所要求的事情。

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

类似的东西:

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。