2009-11-21 32 views

回答

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; 
    } 
} 

此类型映射也接受零,因为我需要一个方式来传递NULL给C函数。

+0

这是一个很好的发现。感谢分享! – 2009-11-30 14:51:01

0

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

+0

我使用SWIG生成Python绑定,所以我认为最简单的方法是重复使用相同的.i文件进行Lua绑定。它的工作正常,除了问题中描述的例外。 感谢您指出其他选项。 – marcin 2009-11-21 21:04:56

0

有没有简单的方法来做你想问什么。

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

喜欢的东西:

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

     FILE* GetFilePointer(); 

     Seek(... 

在痛饮绑定很简单:

%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:但是直接文件。