代码之家  ›  专栏  ›  技术社区  ›  Bernard

我应该如何处理D中的C字符串?

  •  4
  • Bernard  · 技术社区  · 15 年前

    我正在将C库的头文件转换为D模块,我想知道应该如何处理C字符串。

    使用DMD 1,可以:

    void f(char* s);  // Definition for C library's function.
    

    但是,使用dmd 2(我个人使用,但我希望两个模块都能使用)字符串是常量,因此要使用模块来获得相同的代码,需要

    void f(const(char)* s);  // Definition for C library's function.
    

    我该怎么办?只使用 char* 使“客户机”代码以某种方式使字符串可变?或者根据编译代码的编译器的版本修改类型?如果是前者,最好的方法是什么使它们可变?我想,dup会这么做,但是编译器没有一个条。如果是后者,我该怎么做呢?我试过这个:

    version (D_Version2) {
        alias const(char)* charptr;
    } else {
        alias char* charptr;
    }
    
    void f(charptr s);
    

    但是,不幸的是,DMD 2版本对于DMD 1来说不是有效的代码,并且版本块中的所有代码都必须是编译器编译代码的有效代码,即使代码不会包含在生成的可执行文件中。因此,目前代码在这两种情况下都可以编译,但是您必须首先修改别名,正如您可以想象的那样,这并不理想。

    2 回复  |  直到 14 年前
        1
  •  5
  •   Vladimir Panteleev    15 年前

    你可以使用 mixin 构造以使用在所有版本中无效的特定于语言版本的代码。例子:

    static if(version_major<2)
    {
        alias char* charptr;
    }
    else
    {
        mixin("alias const(char)* charptr;");
    }
    

    关于你的实际问题,我建议在C语言与C++的接口定义一个类型的时候做同样的事情。 const(char)* 对于D2和 char* 对于d1,但仅在适当时使用(例如,如果函数 烧焦* 对于要写入的缓冲区,可能不适合命名 const(char)* 像“charptr”这样普通的东西。 LPCSTR 可以工作;

    我不明白“什么是使它们变为可变的最好方法”这个问题。

        2
  •  -1
  •   Taco de Wolff    14 年前

    不要用混音器,这是做这个工作的错误工具。您真正需要的是“version”语句,您可以在这里的条件编译页中阅读它: http://www.digitalmars.com/d/2.0/version.html

    它不会编译/查看不同版本的代码。这允许为不同的D版本或不同的操作系统构建不同的代码。

    mixin可能可以工作,但它是一个沉重的工具,没有突出显示代码(在引号内),只是过于复杂的事情。版本语句非常适合这个问题。