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

发布于 2024-08-11 11:23:15 字数 110 浏览 3 评论 0原文

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

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

瑕疵 2024-08-18 11:23:15

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

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

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

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.

如梦 2024-08-18 11:23:15

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

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.

故人如初 2024-08-18 11:23:15

没有简单的方法可以满足您的要求。

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。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文