2017-04-20 7 views
0

にインポートするにはどうすればDのライブラリからクラスをインポートできますか?
私が間違っていることはありますか?私はdllからlibsを通して関数をインポートしましたが、決してクラスはありませんでした。dlang C++からMagick ++クラスをD

これらのエラーを取得するの.libからクラスをインポートしようとしている:ここで

main.obj : error LNK2019: unresolved external symbol "public: void __cdecl Magick::Image::write(char const *)" ([email protected]@[email protected]@[email protected]) referenced in function _Dmain 
main.exe : fatal error LNK1120: 1 unresolved externals 

は、私はクラスをインポートしようとする方法ですが、私はこれらが正しい定義であると思いますが、間違っているかもしれません:

pragma(lib, "library.lib"); 
extern (C++){ 
    Image createImage(const(char)*); 
    void deleteImage(ref Image d); 
} 

pragma(lib, "C:/Program Files/ImageMagick-7.0.5-Q16/lib/CORE_RL_Magick++_.lib"); 
pragma(lib, "C:/Program Files/ImageMagick-7.0.5-Q16/lib/CORE_RL_MagickCore_.lib"); 
pragma(lib, "C:/Program Files/ImageMagick-7.0.5-Q16/lib/CORE_RL_MagickWand_.lib"); 
extern (C++,Magick){ 
    void InitializeMagick(const(char)*); 
    //void InitializeMagick(const(char)* __ptr64); 
    class Image{ 
     //There are errors trying to import any constructor or function 
     //this(); 
     //this(const(char)*); 
     final void write(const(char)*); 
    } 
} 

int main(string[] args){ 
    Magick.InitializeMagick(""); 
    Magick.Image img = createImage("screenshot:"); 
    img.write("file.jpg"); //linking problems after adding this line 
    return 0; 
} 

これは、私はDにインポートしようとしている機能である:

void Image::write(const string &filename); 
+0

これらのコンストラクタを取り除くと、DにC++クラスを構築することはできません.C++ヘルパ関数を作成して破棄する必要があります。 –

+0

ok私はそれを得るが、ウェブサイトにこの例があると思う:https://dlang.org/spec/cpp_interface.html私は彼らがそれを使用するためにクラスを定義したと思ったが、クラスを追加してください。 – shuji

+1

どのクラスとどの例ですか?最初の「Using C++ Classes from D」には、createInstanceとdestroyInstanceがあり、構築/破棄を扱うことができます。「C++からDクラスを使用する」は、クラスが実際にDとC++で記述されているためです。その場合、新規/削除はC++ではなくDで行う必要があります)。しかし、DのC++クラスを使用する場合は、メンバーを呼び出すことができるようにクラスを定義し、作成することはできません。 –

答えて

1

コンストラクタと両方クラスImageのメソッドは、char*ではなくstd :: stringを取ります。あなたはcreateImageからchar*をcpp側のstd::stringに変換しますが、Image.writeからの苦情はchar*からstd::stringに変換できないため、苦情を受け取っています。
Magick::Imageの場合と同じように、std::stringについてdコンパイラを教えて、std::stringの周りにラッパーを作成する必要があります。
ヒープ上のcpp側にstd::stringを作成し、ポインタを渡すだけの場合は、あまり定型化する必要はありません。ここでの例です:

// wrapper.cpp 
#include <Magick++.h> 
#include <string> 

Magick::Image* createImage(const std::string &imageSpec_) 
{ 
    return new Magick::Image(imageSpec_); 
} 

void deleteImage(Magick::Image *&image) 
{ 
    delete image; 
    image = NULL; 
} 

std::string* createCppString(const char *s) 
{ 
    return new std::string(s); 
} 

void deleteCppString(std::string *&sp) 
{ 
    delete sp; 
    sp = NULL; 
} 
// imm.d 
pragma(lib, "wrapper.lib"); 
extern (C++, std) 
{ 
    // std::string boilerplate 
    struct allocator(T); 
    struct char_traits(CharT); 
    struct basic_string(CharT, Traits=char_traits!CharT, Allocator=allocator!CharT); 
    alias string = basic_string!char; 
} 

pragma(lib, "C:/Program Files/ImageMagick-7.0.5-Q16/lib/CORE_RL_Magick++_.lib"); 
pragma(lib, "C:/Program Files/ImageMagick-7.0.5-Q16/lib/CORE_RL_MagickCore_.lib"); 
pragma(lib, "C:/Program Files/ImageMagick-7.0.5-Q16/lib/CORE_RL_MagickWand_.lib");extern (C++, Magick) 
{ 
    void InitializeMagick(const(char)*); 
    class Image 
    { 
     @disable this(); 
     final void write(ref const(std.string)); 
    } 
} 

extern (C++) 
{ 
    Magick.Image createImage(ref const(std.string)); 
    void deleteImage(ref Magick.Image); 
    std.string* createCppString(const(char)*); 
    void deleteCppString(ref std.string*); 
} 

void main() { 
    Magick.InitializeMagick(""); 

    auto imgsrc = "screenshot:".createCppString; 
    scope(exit) deleteCppString(imgsrc); 

    Magick.Image img = createImage(*imgsrc); 
    scope(exit) deleteImage(img); 

    auto filename = "file.jpg".createCppString; 
    scope(exit) deleteCppString(filename); 

    img.write(*filename); 
} 

しかし、あなたがスタック上にstd::string(CPP側)を作成し、代わりに周りを渡すの谷でそれを周りに渡す場合あなたはより多くのボイラープレートを必要とするポインタ、あなたがbase_string

struct basic_string(CharT, Traits=char_traits!CharT, Allocator=allocator!CharT); 
{ 
    // fill in the fields ... 
} 
のフィールドに記入する必要があります

これを行う最適な方法ですが、それに幸運です(base_string.hはそれほど親切ではありません)。ただし、htodのようなツールをあなたに任せてください。

+1

あなたは正しいですが、std :: stringを定義しようとするのは非常に複雑ですが、私は実際にMagick :: Imageクラスを派生させましたので、write関数をconst char *パラメータでラップすることができました。これをクリアしてくれてありがとう – shuji

関連する問題