我想将 qml 与 d 语言一起使用。但是没有绑定到 d,我想创建它。但我不知道如何开始。请告诉我,如何开始创建绑定。
2 回答
由于没有人回答:
据我了解QML
是建模语言,Qt
我猜它很大程度上取决于Qt
. Qt
我在这里假设它至少在某种程度上取决于。
首先,已经尝试绑定Qt
到D
:http : //www.dsource.org/projects/qtd,但据我所知,这个项目已经死了,不再开发(最后一次提交是在 2 年前)。您可以将其用作您工作的基础或作为如何绑定QML
和Qt
.
1. 选项,C/C++ Glue-Layer
C-Glue 层意味着,您基本上编写了两次代码。你用(可以直接与and交互的语言)编写了一个完整C++
的C
包装器。这意味着您将类的每个方法包装在一个函数中,该函数接受一个指针(指向表示 this 的结构)。这可能看起来像这样(注意这是 GtkWebkit 的抽象,它是用 C 编写的,但该片段演示了如何很好地做到这一点):C++
Qt
Qml
C
C++ Qt class
// 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*
而不是GtkWidget*
,这不是问题的真正解决方案。你很可能也会遇到这个问题,你的 Glue-Layer 结构有你没有抽象的成员,我会在这里使用不透明的结构并为用户真正需要的成员提供功能。
我不会更详细地介绍如何与 C 交互,已经有一些指南:
- http://dlang.org/interfaceToC.html
- http://www.gamedev.net/blog/1140/entry-2254003-binding-d-to-c/
- https://github.com/D-Programming-Deimos(不是指南,而是 C 绑定的集合,可以作为参考)
makind 过程中的最后一步Qt
,Qml
绑定将根据您新制作的内容OOP-Api
重新构建。D
C-Bindings
2.选项,SWIG
/绑定生成器
我不是这方面的专家SWIG
,这就是为什么我只用几句话来介绍它的原因。
您可以使用SWIG
的是为您生成整体C/C++-Glue Layer thingy
。如果你幸运的话,你SWIG-File
只有几个includes
人Qt
会SWIG
为你做所有的工作。如果没有,您必须自己定义规则Classes
,Functions
这可能很乏味(但也比做 更容易和更快1. Option
)。所以SWIG
绝对值得一试!
作为旁注:如果您有一个模板/宏/重/仅标题C++
库,则可能会很棘手,或者在没有选项的情况下。glm
SWIG
glm
还有其他的 Binding-Generators,例如PySide项目开始时Boost.Python
切换到Shiboken
. 我不知道你可以很容易地Shiboken
为其他任何东西生成绑定CPython
,也许可以破解Shiboken
甚至Boost.Python
可以工作?也值得一读:http ://setanta.wordpress.com/binding-c/ 。
QtD
使用QtJambi所以这可能是一个好的开始。
3.选项,D方式
D 有一个很棒的想法extern(C++)
,它理论上允许在C++/D
没有这样的 Glue-Layer 的情况下进行绑定:http: //dlang.org/cpp_interface.html。
好主意,但不幸的是太有限了。例如,尚不支持命名空间(bugzilla 上有一个未解决的问题,我现在找不到)。在我看来extern(C++)
,对于 Qt 来说太有限了。
Manu Evans在D 会议上的第一次演讲中提到了如何使用s 元编程功能成功地绑定到 D。C++
D
简而言之
- Glue-Layer 为您提供
C/C++
了最大的灵活性,它会起作用,但它并不简单,而且是一项特别漫长的任务(我会为相当小的项目执行此操作)。 - SWIG/Binding 生成器,我会采用的方式
Qt
,一旦正确设置,它们就会为您完成所有工作(在最好的情况下)。 extern(C++)
C++
,好主意,对于大多数严肃的项目来说太有限了。
我希望这能让您简要了解您可以做什么以及所需的工作量。
他们已经是一篇关于如何将 C 代码与 D 接口的文章?
通常并不难。获取函数声明并将其放入extern(C)
块中
并且通常这些模块被写入到 ac 包中。例子:
src/
`-- appName
|-- c
| `-- dInterface.d
`-- dwrapper.d
该模块appName.c.dInterface
将使用extern(C)
块定义 C 函数,而模块 appName.dwrapper
将提供一种更适合 dlang 的方式。