Reputation: 3571
I have a C function that takes FILE*
as an argument and I'd like to use this function in Lua, passing Lua file. I guess I need a %typemap
for this. How to write it?
(I just started learning Lua).
Upvotes: 2
Views: 638
Reputation: 3571
Here is the solution that I finally came up with.
In Lua source, in liolib.c, there is a function FILE *tofile (lua_State *L)
, which converts Lua file to C FILE*, but it's not a part of the API. I modified it a bit to make a typemap:
%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;
}
}
This typemap accepts also nil, because I needed a way to pass NULL to the C function.
Upvotes: 5
Reputation: 4036
There's no easy way to do what you're asking.
The Lua File class interface abstracts the underlying implementation. You cannot simply typemap it. You can, however, create a C proxy that wraps FILE operations you need and create an instance of this proxy in Lua using SWIG. You can then generate a typemap to convert a FILE* to a wrapper proxy instance.
Something like:
class MyFileProxy {
private:
FILE* fp;
public:
MyFileProxy(FILE* fp);
MyFileProxy(const char* path);
FILE* GetFilePointer();
Seek(...
In SWIG the binding is simply:
%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
}
You won't be able to use io:File directly, however.
Upvotes: 0
Reputation: 249293
You're using SWIG to generate Lua bindings for your C code? Why not use the Lua C API directly, or if you can use C++, Luabind? I think either of those would be better than trying to make it work with SWIG, unless you've got a strong attachment to SWIG already.
Upvotes: 0