如何正确从 D 接口到 C++?

juf*_*fma 2 c++ gcc d dmd interfacing

我尝试在 C++ 和 D 之间建立接口。

\n

问题是我无法编译它。我使用了网站上的代码/命令行

\n
> g++ -c foo.cpp\n> dmd bar.d foo.o -L-lstdc++ && ./bar\n
Run Code Online (Sandbox Code Playgroud)\n

它不起作用:首先,DMD编译器不使用.o文件,所以我必须手动指定创建.obj文件,然后链接器抛出错误,因为它不知道/lstdc++,所以我配置了手动编译 cpp 库。

\n

这就是我现在遇到的问题,它抛出“找不到符号”错误,我不知道如何解决这个问题,我在编译时做错了什么吗?或者是在编程网站上?

\n

这是我的编译命令:

\n
PS C:\\Users\\kunde\\Downloads\\d-interface test> g++ -c -o test-cpp.obj test.cpp\nPS C:\\Users\\kunde\\Downloads\\d-interface test> dmd -L"G:\\GNUstep\\lib\\gcc\\mingw32\\4.6.1\\libstdc++.dll.a" -L"G:\\GNUstep\\lib\\gcc\\mingw32\\4.6.1\\libstdc++.a" .\\test-cpp.obj .\\test.d\ntest.obj : error LNK2019: Verweis auf nicht aufgel\xc3\xb6stes externes Symbol ""char __cdecl foo(int)" (?foo@@YADH@Z)" in Funktion "__Dmain".\ntest-cpp.exe : fatal error LNK1120: 1 nicht aufgel\xc3\xb6ste Externe\nError: linker exited with status 1120\n
Run Code Online (Sandbox Code Playgroud)\n

和我的代码:\ntest.d:

\n
import std.stdio;\n\nextern (C++) char foo(int i);\n\nvoid main(string[] args)\n{\n    writefln("%c", foo(14));\n}\n
Run Code Online (Sandbox Code Playgroud)\n

测试.cpp:

\n
#include <iostream>\n\nextern "C" {\n    #include "test.h"\n}\n\nchar foo(int i){\n    std::cout << "got: ";\n    return (char)bar(i);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

和测试.h:

\n
#include <stdio.h>\n\nint bar(int a){\n    printf("returned %d", a*a);\n    return a*a;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我究竟做错了什么?

\n

PS:我是德国人,所以错误可能需要翻译

\n

编辑:正如答案中所述,MSVC 解决了问题,我将“g++ -c -o test-cpp.obj test.cpp”更改为“cl test.cpp -c /EHsc”

\n

Ada*_*ppe 5

C++ 是一个挑剔的野兽 - 它的名称修改细节是实现定义的,因此它因平台和编译器而异。dmd 选择一个它认为是系统上的主编译器并复制它。在 Linux 上,它是 g++...但在 Windows 上,它是 Microsoft C++,而不是 g++。

所以你必须使用匹配的编译器。在 Windows 上,有 gdc 编译器 - gcc 中内置的 D 编译器 - 但目前没有可用的二进制版本。你必须用一些配置标志自己编译它......

../gcc/configure --prefix=/mingw64 --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --disable-bootstrap --disable-werror --disable-libssp --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libitm  --disable-libsanitizer --disable-libstdcxx-pch --with-arch=x86-64 --with-gnu-as --with-gnu-ld --with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64 --with-isl=/mingw64 --with-native-system-header-dir=/mingw64/x86_64-w64-mingw32/include --libexecdir=/mingw64/lib --enable-languages=d --enable-libphobos --enable-shared --enable-static --disable-multilib
Run Code Online (Sandbox Code Playgroud)

是我用过的。

有点痛。我也从未在 gdc/Windows 上实际测试过 extern(C++)。

因此,我建议要么在 C++ 上使用 MSVC 编译器以及 dmd...,要么更好地制作接口extern(C)。C 接口在事物之间的兼容性要好得多。

.o 与 .obj 的情况是相同的 - gcc 使用 .o,dmd 和 msvc 使用 .obj (至少 -m64 位构建匹配,32 位更复杂,具体取决于版本号)...所以真正使用相同的编译器系列将为您带来最佳结果。