dlang 如何将 Magick++ class 从 C++ 导入 D
dlang How to import a Magick++ class from C++ into D
如何从 D 中的库导入 class?
我做错了什么吗?我已经成功地通过库从 dll 导入了函数,但从来没有 class.
尝试从 .lib 导入 class 出现这些错误:
main.obj : error LNK2019: unresolved external symbol "public: void __cdecl Magick::Image::write(char const *)" (?write@Image@Magick@@QEAAXPEBD@Z) referenced in function _Dmain
main.exe : fatal error LNK1120: 1 unresolved externals
这是我尝试导入 class 的方式,我认为这些是正确的定义,但可能是错误的:
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);
class Image
的构造函数和 write
方法都采用 std::string 而不是 char*
。您没有收到来自 createImage
的投诉,因为它在 cpp 端将 char*
转换为 std::string
,但是您收到来自 Image.write
的投诉,因为 D 编译器无法转换 char*
到 std::string
.
您需要向 d 编译器传授有关 std::string
的知识,并以与 Magick::Image
.
相同的方式围绕 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 端)并通过 vale 传递它而不是传递指针你需要更多样板,你需要填写base_string
的字段
struct basic_string(CharT, Traits=char_traits!CharT, Allocator=allocator!CharT);
{
// fill in the fields ...
}
这是最好的方法,但祝你好运(base_string.h
不是很友好),但你可以让工具为你完成艰苦的工作,例如 htod。
如何从 D 中的库导入 class?
我做错了什么吗?我已经成功地通过库从 dll 导入了函数,但从来没有 class.
尝试从 .lib 导入 class 出现这些错误:
main.obj : error LNK2019: unresolved external symbol "public: void __cdecl Magick::Image::write(char const *)" (?write@Image@Magick@@QEAAXPEBD@Z) referenced in function _Dmain
main.exe : fatal error LNK1120: 1 unresolved externals
这是我尝试导入 class 的方式,我认为这些是正确的定义,但可能是错误的:
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);
class Image
的构造函数和 write
方法都采用 std::string 而不是 char*
。您没有收到来自 createImage
的投诉,因为它在 cpp 端将 char*
转换为 std::string
,但是您收到来自 Image.write
的投诉,因为 D 编译器无法转换 char*
到 std::string
.
您需要向 d 编译器传授有关 std::string
的知识,并以与 Magick::Image
.
相同的方式围绕 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 端)并通过 vale 传递它而不是传递指针你需要更多样板,你需要填写base_string
的字段
struct basic_string(CharT, Traits=char_traits!CharT, Allocator=allocator!CharT);
{
// fill in the fields ...
}
这是最好的方法,但祝你好运(base_string.h
不是很友好),但你可以让工具为你完成艰苦的工作,例如 htod。