【问题标题】:How Do I Pass Strings Between D and C++?如何在 D 和 C++ 之间传递字符串?
【发布时间】:2015-12-11 09:44:04
【问题描述】:

我尝试调整这个答案...

https://stackoverflow.com/a/26924384/105539

...所以我将一个 C++ 字符串传递给 D,然后用“-response”返回它,但它无法编译 D 文件:

// dtest.d
extern (C++) string dfunc(string s) {
        return s ~ "response";
}

$ dmd -c dtest.d
Error: Internal Compiler Error: unsupported type string

dmd: cppmangle.c:576: virtual void CppMangleVisitor::visit(Type*): Assertion `0' failed.
Aborted (core dumped)

然后,我不知道如何编写 C++ 文件以使其正确传递此值并正确接收。

【问题讨论】:

  • 即使这不应该工作,D 编译器也不应该因内部编译器错误而崩溃。可能想要提交错误报告。
  • 我发现我今天可以通过 brew 使用 sudo brew update; sudo brew upgrade dmd 更新我的 dmd。现在我有了,同样的代码补丁返回Error: Internal Compiler Error: unsupported type string 然后Segmentation fault: 11 所以,看起来编译器现在已经修复了这个错误。同时,我们在下面有一个答案。
  • 不,没有;仍然存在内部编译器错误,然后是段错误。这两种情况都不应该发生。

标签: c++ string d


【解决方案1】:

您可以使用std.string.toStringz 从 D 传递一个以空字符结尾的 C 字符串。同样的还有std.string.fromStringz:

extern (C++) immutable(char)* dfunc(const char* s) {
    import std.string;
    return toStringz(fromStringz(s) ~ "response");
}

然后是 C++ 中的调用者

#import <Cocoa/Cocoa.h>
char *dfunc(const char *);
extern "C" int rt_init();
extern "C" int rt_term();

int main(int argc, const char * argv[]) {

        const char *sTest = "request";
        rt_init();
        NSLog(@"Result=%s",dfunc(sTest));
        rt_term();

  return NSApplicationMain(argc, argv);
}

【讨论】:

  • 这几乎奏效了。我不得不将输入参数更改为const char* s,这就是我如何将它包含在我的 main.mm 文件中的 XCode 中:pastebin.com/9s1WAr2t(临时 pastebin)也许你可以通过展示它在 C++ 中的调用方式来改进你的答案,就像我一样在我的临时粘贴箱中显示?
  • 完成,但您可以在审阅者接受更改后自己改进答案。我什至认为您在 S.O 上有足够的业力来编辑答案,而无需第三方审核。
  • 我愿意,但对你有礼貌。 :) 另外,你在这个话题上比我知识渊博,我现在觉得,所以我想你可能会说“是的,但是......”然后继续向我展示一些我可能错过的东西,即使我找到了答案. (有时会发生这种情况。)
【解决方案2】:

D 字符串是一个具有char*size_t 长度的结构。这与 std::string 不兼容

避免这种情况的常见方法是恢复为 C 风格的 API 设计,在这种设计中直接传递 char* 和长度。

这也意味着您必须小心分配和释放,因为 D 分配器与 C++ 分配器不直接兼容,并且 D 的垃圾回收不会扫描 C++ 内存中的指针。

【讨论】:

    【解决方案3】:

    这个问题已经在 SO 上被问过很多次了。我认为这里给出了最好的答案之一:https://stackoverflow.com/a/6405870/876497

    注意:请放心,答案是与 C 相关的,但它也可以应用于 C++。

    【讨论】:

    • 如果您认为这个问题是重复的,那么请标记它。否则,请在问题本身中包含链接的相关部分;仅链接的答案容易受到链接腐烂的影响。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    相关资源
    最近更新 更多