实验环境:
VisualD+Vs2003
ms-coff格式
需要在D语言中调用C++的std::string并不是不可能,是要注意一些问题。在C++中使用string时,很多时候是会使用以下方式:
string getStdString(){ … } 和 printStdString(string str);
还有一种是:
string& getStdString(){ … } 和 printStdString(string& str);
很不幸运的是,这两种方式是没办法在D语言中调用的,因为std::string是class类型,如果是struct就没有问题。具体的实验参考:
http://www.cnblogs.com/wanhongnan/p/5780761.html
跟据这篇的分析,使用以下形式是不是能调用std::string呢?本文来做一个测试与分析:
string* getStdString(){…} 和 void printStdString(string* a)
创建工程:
#include "stdio.h" using namespace std; #include <string> #include <iostream> void printStdString(string* a){ cout << *a << endl; delete a; } string* getStdString(){ string* str = new string("abc"); return str; }
编译后,查看test.o文件,分析printStdString函数的符号:
?printStdString@@YAXPAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
basic_string 为 PAV 类型 , 类指针类型
char_traits 为 U 类型, 结构值类型
allocator 为 V 类型, 类值类型
从这里看,这样调用还是会有一个allocator 为类值类型,可能本实验会遇到麻烦。
再完成D语言中的调用.
stl.d文件
module stl; extern(C++,std){ class allocator(CharT){} struct char_traits(CharT){} class basic_string(CharT, CharTraits = char_traits!(CharT) , Allocator = allocator!(CharT)){} } extern(C++){ alias String = std.basic_string!(char); void printStdString(String str); String getStdString(); }
main.d文件:
import std.stdio; import stl; int main(string[] argv){ auto str = getStdString(); printStdString(str); readln(); return 0; }
编译,果然通不过,错误如下:
还是没办法调用,连接时出现失败
来分析一下出错的原因:
在C++中导出的符号中allocator为V类型,而D语言中allocator调用的符号则为PAV类型,因此连接失败。
而在D语言怎么使用类的值类型目前还不知道怎么解决。
怎么办?还需要继续的研究……
在dlang.org中介绍:
When mapping a D class onto a C++ struct, use extern(C++, struct) to avoid linking problems with C++ compilers (notably MSVC) that distinguish between C++'s class and struct when mangling. Conversely, use extern(C++, class)to map a D struct onto a C++ class.
引用自:http://dlang.org/spec/cpp_interface.html
stl.d将代码修改为:
module stl; extern(C++, class , std) struct allocator(CharT){} extern(C++,std) { struct char_traits(CharT){} class basic_string(CharT, CharTraits = char_traits!(CharT) , Allocator = allocator!(CharT)){} } extern(C++) { alias String = std.basic_string!(char); void printStdString(String str); String getStdString(); }
编译时出错。
是 extern(C++, class , std)语法不支持吗? 这个要是支持,D调用C++无任何问题了。
原来是bug,期待中。
--------------------------------------------------------------------------------------------------------------------------------------------------
终于调用成功了。参见:http://www.cnblogs.com/wanhongnan/p/5790605.html
作者:宛宏南