澄清在c ++中实现FUSE文件系统

时间:2013-05-18 09:00:07

标签: c++ fuse

我正在尝试实现一个FUSE文件系统,并在阅读之后。我想我已经找到了如何实现它。我会说明我对实施的想法。如果对或错,请告诉我。

实现文件系统需要使用任何人认为合适的函数(例如xmp_getattributes表示getattr函数)实现的操作,然后将这些函数映射到结构中的相应函数。输入fuse_operations

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

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

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

我说错了吗?另外,有没有其他方法在C ++中实现FUSE,这比static struct声明更好?

4 个答案:

答案 0 :(得分:4)

  

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

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

这是错误的。 FUSE需要一个指向函数的指针,但ExFuse::getAttributes是指向成员方法的指针(因为你没有明确说它是一个静态方法,我只能假设它是一个成员方法)。 They are not the same thing.

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

  

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

我不敢。 FUSE是用C语言编写的,希望你坚持使用“C方式”。就公共接口而言,这对于使用C ++范例几乎没有余地(当然,只要你不扔,你可以在私有实现中做你想做的事,但这对你没有帮助你把界面写到FUSE)。

答案 1 :(得分: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);

除非&#34;方法&#34;被宣布为静止的,它绕过&#34;这个&#34;幕后指针。 FUSE界面的所有原型都是错误的。

你可以在FUSE中使用C ++,但是使用类来定义结构并没有什么意义。你可以自由地使用向量,字符串等 - 但是也要考虑使用C ++(如果你正确地使用它就不会成为任何东西) - 但除非你熟悉C ++ - &gt; C转换(C ++过去基本上是C预处理器),尽可能地坚持使用C语义。

答案 2 :(得分:0)

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

根据@ user6269400,使用C ++类方法进行FUSE操作的主要问题是 col1 col2 0 40188e5464645645 54634565754 1 401884645645564 54545454564 2 401087465836453 54545454565 3 401885645656567 53434343435 4 401084569498484 54342340788 5 401088465836453 56767686334 6 401439569345656 64545467558 7 401012993933334 55645342352 8 401034545566463 34353463464 指针指向的内容-或更重要的是,我们如何获得实现FUSE操作的类方法以实现以下目的:在正确的上下文中被调用,即作为C ++类实例上的方法调用。

一个简单的答案是使用FUSE context's private_data field存储指向实例的指针,然后使用一些粘合代码将其转换为您的类类型。

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

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()取消引用),则您会得到不确定的行为(充其量是细分错误)。

因此,我们很清楚-我不建议使用FusePP:生成的代码将不是C ++,但看起来与C ++足够相似,以使编译器和人员蒙受巨大灾难。但我认为,采用相同的方法并使用更多的粘合代码来拦截FUSE操作调用,将上下文this_()转换为类实例指针,然后通过实例指针调用C ++方法将非常可行。

答案 3 :(得分:0)

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

如果我开发更多,这个库的 API 可能会改变。