【问题标题】:Using a DLL exported from D使用从 D 导出的 DLL
【发布时间】:2016-09-21 16:28:32
【问题描述】:

我在 D 中创建了一个简单的加密程序,我想用它创建一个 DLL 并尝试将其导入到 Python 中。

我可以简单地调用我的main 函数,因为它不需要任何参数。但是当我谈到我的加密方法时,它使用动态长度 ubyte[] 数组,但据我所知,它们在其他基于 C/C++ 的语言中不存在强>。

例如,我的一个函数的第一行是:
ubyte[] encode(ubyte[] data, ubyte[] key){

但是我不能在其他语言中使用没有固定长度的数组! 例如,如何在 Python 中导入该函数?

编辑:

我知道我可以创建一个包含指针和数组长度的包装器,但是没有更优雅的解决方案吗?
(这里我不需要使用 D 来使用 D 编写的库)

【问题讨论】:

  • 我不确定你在 Python 中到底是怎么做的,但是 C 包装器可以通过创建一个接受数据指针和长度的小函数来完成,然后将其转发到切片.因此,如果您能弄清楚如何将 Python 数组转换为 C 数组,那么您可以将 C 转换为 D,然后就可以了。
  • @AdamD.Ruppe 是的,这是我的第一个想法。看起来不错,但我认为有更优雅的解决方案。
  • 也许这有帮助:wiki.dlang.org/Win32_DLLs_in_D
  • dlang.org/spec/interfaceToC.html 似乎在C 中没有任何type[] 的匹配类型...
  • 也许您已经可以使用 pyd (github.com/ariovistus/pyd) 做到这一点??

标签: python dll d


【解决方案1】:

好吧。除了用长度包装指针或包装到 C 数组然后再包装到 D 之外,没有真正优雅的方法。

但是,您可以通过第一种方式使用具有指针、长度和将其转换为 D 数组的属性的结构来实现一些优雅的目的。

然后,您导出的函数采用您的结构,该函数应该做的就是调用一个内部函数,该函数采用一个实际的 D 数组,您只需将数组传递给它,转换就会在那时通过别名 this 和转换属性。

这里有一个示例用法: 主模块;

import core.stdc.stdlib : malloc;

import std.stdio;

struct DArray(T) {
    T* data;
    size_t length;
    /// This field can be removed, only used for testing purpose
    size_t offset;

    @property T[] array() {
        T[] arr;

        foreach(i; 0 .. length) {
            arr ~= data[i];
        }

        return arr;
    }

    alias array this;

    /// This function can be removed, only used for testing purpose
    void init(size_t size) {
        data = cast(T*)malloc(size * T.sizeof);
        length = size;
    }

    /// This function can be removed, only used for testing purpose
    void append(T value) {
        data[offset] = value;

        offset++;
    }
}

// This function is the one exported
void externalFoo(DArray!int intArray) {
    writeln("Calling extern foo");

    internalFoo(intArray);
}

// This function is the one you use
private void internalFoo(int[] intArray) {
    writeln("Calling internal foo");

    writeln(intArray);
}


void main() {
    // Constructing our test array
    DArray!int arrayTest;
    arrayTest.init(10);

    foreach (int i; 0 .. 10) {
        arrayTest.append(i);
    }

    // Testing the exported function 
    externalFoo(arrayTest);
}

这是一个绝对最低版本的操作方法

struct DArray(T) {
    T* data;
    size_t length;

    @property T[] array() {
        T[] arr;

        foreach(i; 0 .. length) {
            arr ~= data[i];
        }

        return arr;
    }

    alias array this;

}

// This function is the one exported
void externalFoo(DArray!int intArray) {
    writeln("Calling extern foo");

    internalFoo(intArray);
}

// This function is the one you use
private void internalFoo(int[] intArray) {
    writeln("Calling internal foo");

    writeln(intArray);
}

【讨论】:

  • 看起来不错,但是,使用 C 包装器来处理指针和长度更简单。
猜你喜欢
  • 1970-01-01
  • 2021-09-17
  • 2013-10-23
  • 2019-12-28
  • 2011-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多