D语言中调用C++的std::string遇到的问题分析

实验环境:

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)

创建工程:     

   image test.cpp

#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;
}

编译,果然通不过,错误如下:

image

还是没办法调用,连接时出现失败

来分析一下出错的原因:

image 在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();
}

       编译时出错。

image

      是 extern(C++, class , std)语法不支持吗? 这个要是支持,D调用C++无任何问题了。

      

2`B1()RBLU3U`1%DVB@]P~C

      原来是bug,期待中。

--------------------------------------------------------------------------------------------------------------------------------------------------

      终于调用成功了。参见:http://www.cnblogs.com/wanhongnan/p/5790605.html

作者:宛宏南

原文地址:https://www.cnblogs.com/wanhongnan/p/5782633.html