2009-11-21 65 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:但是直接文件。