3

I am trying to implement a FUSE filesystem, and after reading around. I think I have found out how to implement it. I would state out what my idea is of the implementation. Please let me know if it is right or wrong.

One implements the operations that is required to be implemented by the filesystem using whatever functions one sees fit (say xmp_getattributes for getattr function) and then maps those functions to the corresponding functions in a struct of type fuse_operations

static struct fuse_operations xmp_oper = 
{
    .getattr = xmp_getattributes,
    //more declarations...
};

Now, if I have used a class ExFuse to implement a FUSE filesystem and I have a method ExFuse::getAttributes which does the job of getattr in the implementation. Then, my declaration would change as

static struct fuse_operations xmp_oper = 
{
    .getattr = ExFuse::getAttributes,
    //more declarations...
};

Am I correct? Also, is there any other way of implementing FUSE in C++ which is better than the static struct declaration?

4

4 回答 4

4

如果我使用了一个类ExFuse来实现 FUSE 文件系统,并且我有一个方法可以在实现ExFuse::getAttributes中完成工作getattr。然后,我的声明将更改为

static struct fuse_operations xmp_oper = 
{
    .getattr = ExFuse::getAttributes,
    //more declarations...
};

这是错误的。FUSE 需要一个指向函数的指针,但ExFuse::getAttributes它是一个指向成员方法的指针(因为你没有明确说它是一个静态方法,我只能假设它是一个成员方法)。它们不是同一件事。

您要么需要使用普通函数,要么需要使用静态方法。

有没有比静态结构声明更好的在 C++ 中实现 FUSE 的其他方法?

恐怕不是。FUSE 是用 C 语言编写的,希望您坚持“C 方式”。就公共接口而言,这使您几乎没有使用 C++ 范例的余地(当然,您可以在私有实现中做很多您想要的事情,只要您不抛出,但这无济于事您编写 FUSE 的接口)。

于 2013-05-18T09:29:24.750 回答
1

上面也已经说过,你的类的所有方法都必须是“静态的”。这是因为当你在 C++ 中有这样的类时:

class example
{
  example ()
  int method (int i) {cout << i << '\n';}
};

int main (int argc, char **argv)
{
  example ex;

  ex.method (1);
}

当您调用上面的 ex.method(1) 时,真正发生的是这个调用:

{NameMangling}method (&ex, 1);

除非“方法”被声明为静态的,否则它会在幕后传递“this”指针。对于 FUSE 界面,您的所有原型都是错误的。

您可以在 FUSE 中很好地使用 C++,但是使用类来定义结构没有什么意义。你可以自由地使用向量、字符串等——但也要考虑使用 C++ 的开销(如果你正确地使用它就不会有任何开销)——但除非你熟悉 C++->C 翻译( C++ 在糟糕的过去基本上是一个 C 预处理器),尽量坚持 C 语义。

于 2017-05-26T20:52:36.777 回答
0

免责声明:我没有测试以下答案中的任何假设

根据@user6269400,使用 C++ 类方法进行 FUSE 操作的主要问题是this指针指向什么 - 或者更重要的是,我们如何让实现 FUSE 操作的类方法在正确的上下文中被调用,即作为对 C++ 类实例的方法调用。

一个简单的答案是使用FUSE 上下文的private_data字段来存储指向实例的指针,然后使用一些胶水代码将其转换为您的类类型。

一个“库”(我在这里非常宽松地使用这个术语)实现(一些)用于 C++ FUSE 实现的胶水代码可以在这里找到:https ://github.com/jachappell/Fusepp 。它的工作方式是将正确命名的非静态类方法挂钩到 FUSE 操作表,然后使用类实例地址作为“ private_data”来初始化 FUSE。正如@syam 所暗示的那样,这样做会使 FUSE 使用不正确的(可能是nullthis地址调用您的类方法,结果将是一个非常不愉快的 C++ 代码。Fusepp 尝试通过提供一种this_()为您执行上述转换的方法来解决此问题,因此您的代码可能如下所示:

const bool ExFuse::resolve_path(const std::string &path, struct stat* stbuf) {
    // ...
}

int ExFuse::getattr(const char *path, struct stat *stbuf, struct fuse_file_info *)
{
    memset(stbuf, 0, sizeof(struct stat));
    if (!this_()->resolve_path(stbuf))
        return -ENOENT;
    return 0;
}

因此,您必须使用this_()来访问您的实例成员,并且没有隐含的this- 如果您尝试resolve_path()直接调用(不通过取消引用this_()),您将获得未定义的行为(充其量是分段错误)。

我们很清楚 - 我不建议使用 FusePP:生成的代码不会是 C++,但看起来与 C++ 足够相似,从而可能会造成灾难性的后果来愚弄编译器和人类。但是采用相同的方法并使用更多的胶水代码来拦截 FUSE 操作调用,将上下文private_data转换为类实例指针,然后通过实例指针调用 C++ 方法将是非常可行的,我相信。

于 2019-04-24T08:12:21.340 回答
0

我开始在https://github.com/xloem/fusexx上为使用 C++ 范例的 Fuse 开发 C++ 包装器。如果你看看它是如何工作的,它可能非常直观。它存储一个this指针并使用样板转发函数将静态函数转换为虚拟函数。

如果我进一步开发,这个库的 API 可能会改变。

于 2021-05-16T16:54:20.317 回答