我想在d语言中使用qml。但是没有绑定到d,我想创建它。但我不知道如何开始。请告诉我,如何开始创建绑定。
答案 0 :(得分:6)
由于没有人回答:
根据我的理解,QML
是Qt
的建模语言,我想这很大程度上取决于Qt
。我假设这至少取决于Qt
,至少在某种程度上。
首先,已经尝试将Qt
绑定到D
:http://www.dsource.org/projects/qtd,但是从我听到的这个项目有点死了而且不再开发(最后一次提交) 2年前)。您可以将其用作工作的基础,或作为 绑定QML
和Qt
的方式的参考。
C-Glue Layer意味着,您基本上编写了两次代码。您在C++
中编写了一个完整的C
到C++
包装器(可以直接与Qt
和Qml
连接的语言)。这意味着您将一个类的每个方法都包含在一个C
函数中,该函数接受一个Pointer(表示此C++ Qt class
的结构)。这看起来像这样(注意这是GtkWebkit的抽象,用C语言编写,但代码片段演示了如何做得很好):
// somewhere in a header
typedef struct SurfiClient {
GtkWidget *window; // Offscreen window
// ....
}
typedef GdkPixbuf Pixbuf;
extern "C" {
Pixbuf* surfi_client_get_pixbuf(SurfiClient* client)
{
// in C++ this would gtk_offscreen_window_get_pixbuf would be a method of client->window
return gtk_offscreen_window_get_pixbuf(GTK_OFFSCREEN_WINDOW(client->window));
}
// here go the rest of these functions, probably thousands
}
您必须基本上为D后面想要界面的所有内容执行此操作。更糟糕的是,您还需要为namespaces
和未标记为extern "C"
的免费函数执行此操作,这可能如下所示(libsquish
):
typedef unsigned char u8;
extern "C" {
void CompressMasked(u8 const* rgba, int mask, void* block, int flags) {
squish::CompressMasked(rgba, mask, block, flags);
}
}
正如你现在所看到的,这很乏味......
假设您已完成C/C++
Glue-Layer的制作,现在您必须在D
中创建可以与之对接的代码。
继续使用gtk
示例:
extern(C) {
// Using an opaque struct is one option
struct SurfiClient;
// the other is to wrap the struct correctly
struct SurfiClient {
GtkWidget *window;
}
// The Pixbuf was only a typedef to GdkPixbuf which is already an opaque data structure, easy
struct Pixbuf;
Pixbuf* surfi_client_get_pixbuf(SurfiClient* client);
}
你在这个例子中看到一个问题,如果你想正确包装SurfiClient
结构,你还必须包裹GtkWidget
或者做错了并使用void*
代替{{ 1}},这不是问题的真正解决方案。你很可能也遇到这个问题,你的Glue-Layer结构有你没有抽象的成员,我会带着不透明的结构去这里,并为用户真正需要的成员提供函数。
我没有详细介绍如何与C接口,已经有一些指南:
makind GtkWidget*
,Qt
绑定过程的最后一步是根据您新制作的Qml
重建OOP-Api
中的D
。
SWIG
/绑定生成器我不是SWIG
的专家,这就是为什么我只用几句话来覆盖它。
您可以使用C-Bindings
来为您生成整个SWIG
。如果您很幸运,C/C++-Glue Layer thingy
只包含少数SWIG-File
到includes
,Qt
将为您完成所有工作。如果没有,您必须自己定义SWIG
和Classes
的规则,这可能很乏味(但也比执行Functions
更容易,更快)。所以1. Option
绝对值得一试!
作为旁注:如果您有模板/宏/重/标题SWIG
像glm
C++
这样的库可能会很棘手,或者SWIG
没有选择。
还有其他绑定发生器,例如: PySide项目以glm
开头,然后切换为Shiboken
。我不知道除Boost.Python
之外的其他任何内容都可以轻松生成与Shiboken
绑定的内容,也许是攻击CPython
甚至Shiboken
可能有效?另外值得一读:http://setanta.wordpress.com/binding-c/。
Boost.Python
使用了QtJambi,所以这可能是一个好的开始。
D拥有QtD
的好主意,它允许在理论上制作extern(C++)
绑定,而不需要这样的胶水层:http://dlang.org/cpp_interface.html。
好主意,但不幸的是太有限了。例如。还没有对命名空间的支持(bugzilla上有一个开放的问题,我现在找不到)。在我看来,C++/D
对Qt来说太有限了。
Manu Evans在first talk D conference中提及如何使用extern(C++)
元编程功能成功地与D绑定C++
。
D
Glue-Layer为您提供最大的灵活性,它会起作用,但并不简单,尤其是长期任务(我会为相当小的项目执行此操作)。C/C++
的方式一样,一旦正确设置,它们就会为你完成所有工作(在最好的情况下)。Qt
,好主意,对于最严重的extern(C++)
项目来说太有限了。我希望这能简要介绍一下您可以做些什么以及它需要的工作量。
答案 1 :(得分:1)
他们已经是一篇关于此目的的文章how to interface C code to D?
通常并不难。获取函数声明并将其放入extern(C)
块
通常这些模块都写入c包。例如:
src/
`-- appName
|-- c
| `-- dInterface.d
`-- dwrapper.d
模块appName.c.dInterface
将使用extern(C)
块定义C函数
虽然模块ppName.dwrapper
将提供更适合dlang的方式。