3

我想将 qml 与 d 语言一起使用。但是没有绑定到 d,我想创建它。但我不知道如何开始。请告诉我,如何开始创建绑定。

4

2 回答 2

6

由于没有人回答:

据我了解QML是建模语言,Qt我猜它很大程度上取决于Qt. Qt我在这里假设它至少在某种程度上取决于。

首先,已经尝试绑定QtDhttp : //www.dsource.org/projects/qtd,但据我所知,这个项目已经死了,不再开发(最后一次提交是在 2 年前)。您可以将其用作您工作的基础或作为如何绑定QMLQt.

1. 选项,C/C++ Glue-Layer

C-Glue 层意味着,您基本上编写了两次代码。你用(可以直接与and交互的语言)编写了一个完整C++C包装器。这意味着您将类的每个方法包装在一个函数中,该函数接受一个指针(指向表示 this 的结构)。这可能看起来像这样(注意这是 GtkWebkit 的抽象,它是用 C 编写的,但该片段演示了如何很好地做到这一点):C++QtQmlCC++ 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 交互,已经有一些指南:

  1. http://dlang.org/interfaceToC.html
  2. http://www.gamedev.net/blog/1140/entry-2254003-binding-d-to-c/
  3. https://github.com/D-Programming-Deimos(不是指南,而是 C 绑定的集合,可以作为参考)

makind 过程中的最后一步QtQml绑定将根据您新制作的内容OOP-Api重新构建。DC-Bindings

2.选项,SWIG/绑定生成器

我不是这方面的专家SWIG,这就是为什么我只用几句话来介绍它的原因。

您可以使用SWIG的是为您生成整体C/C++-Glue Layer thingy。如果你幸运的话,你SWIG-File只有几个includesQtSWIG为你做所有的工作。如果没有,您必须自己定义规则ClassesFunctions这可能很乏味(但也比做 更容易和更快1. Option)。所以SWIG绝对值得一试!

作为旁注:如果您有一个模板/宏/重/仅标题C++库,则可能会很棘手,或者在没有选项的情况下。glm SWIGglm

还有其他的 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++,好主意,对于大多数严肃的项目来说太有限了。

我希望这能让您简要了解您可以做什么以及所需的工作量。

于 2013-06-29T10:54:02.240 回答
1

他们已经是一篇关于如何将 C 代码与 D 接口的文章?

通常并不难。获取函数声明并将其放入extern(C)块中

并且通常这些模块被写入到 ac 包中。例子:

src/
`-- appName
    |-- c
    |   `-- dInterface.d
    `-- dwrapper.d

该模块appName.c.dInterface将使用extern(C)块定义 C 函数,而模块 appName.dwrapper将提供一种更适合 dlang 的方式。

于 2013-06-24T21:21:58.927 回答