使用从 D 导出的 DLL
Using a DLL exported from D
我在 D 中创建了一个简单的加密程序,我想从中创建一个 DLL 并尝试将其导入,例如,Python。
我可以简单地调用我的 main
函数,因为它不需要任何参数。但是当我使用我的加密方法时,它使用动态长度 ubyte[]
数组,但据我所知,它们 在其他方法中不存在C/C++ 基于语言.
例如,我的一个函数的第一行是:
ubyte[] encode(ubyte[] data, ubyte[] key){
但是我不能在其他语言中使用没有固定长度的数组!
如何导入该函数,例如,在 Python?
中
编辑:
我知道我可以创建一个带有指针和数组长度的包装器,但是没有更优雅的解决方案吗?
(我不需要使用 D 来使用用 D 编写的库)
好吧。除了用长度包装指针或包装到 C 数组然后到 D 之外,没有真正优雅的方法。
但是,您可以通过第一种方式使用具有指针、长度和将其转换为 D 数组的 属性 的结构来达到某种优雅的目的。
然后你导出的函数接受你的结构,该函数应该做的就是调用一个接受实际 D 数组的内部函数,你只需将数组传递给它,转换就会在那个时刻通过别名发生这和转换 属性.
示例用法如下:
主模块;
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);
}
我在 D 中创建了一个简单的加密程序,我想从中创建一个 DLL 并尝试将其导入,例如,Python。
我可以简单地调用我的 main
函数,因为它不需要任何参数。但是当我使用我的加密方法时,它使用动态长度 ubyte[]
数组,但据我所知,它们 在其他方法中不存在C/C++ 基于语言.
例如,我的一个函数的第一行是:
ubyte[] encode(ubyte[] data, ubyte[] key){
但是我不能在其他语言中使用没有固定长度的数组! 如何导入该函数,例如,在 Python?
中编辑:
我知道我可以创建一个带有指针和数组长度的包装器,但是没有更优雅的解决方案吗?
(我不需要使用 D 来使用用 D 编写的库)
好吧。除了用长度包装指针或包装到 C 数组然后到 D 之外,没有真正优雅的方法。
但是,您可以通过第一种方式使用具有指针、长度和将其转换为 D 数组的 属性 的结构来达到某种优雅的目的。
然后你导出的函数接受你的结构,该函数应该做的就是调用一个接受实际 D 数组的内部函数,你只需将数组传递给它,转换就会在那个时刻通过别名发生这和转换 属性.
示例用法如下: 主模块;
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);
}