mirror of https://github.com/adamdruppe/arsd.git
com.d: support (multi-dimensional) array paramters
This commit is contained in:
parent
d13828c50b
commit
41f09eae3a
90
com.d
90
com.d
|
@ -358,6 +358,8 @@ struct ComProperty {
|
||||||
&argError // arg error
|
&argError // arg error
|
||||||
);//, "Invoke");
|
);//, "Invoke");
|
||||||
|
|
||||||
|
VariantClear(&vargs[0]);
|
||||||
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
if(FAILED(hr)) {
|
if(FAILED(hr)) {
|
||||||
if(hr == DISP_E_EXCEPTION) {
|
if(hr == DISP_E_EXCEPTION) {
|
||||||
|
@ -431,6 +433,12 @@ struct ComProperty {
|
||||||
);//, "Invoke");
|
);//, "Invoke");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static if(args.length) {
|
||||||
|
foreach (ref v; vargs[]) {
|
||||||
|
VariantClear(&v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
if(FAILED(hr)) {
|
if(FAILED(hr)) {
|
||||||
if(hr == DISP_E_EXCEPTION) {
|
if(hr == DISP_E_EXCEPTION) {
|
||||||
|
@ -546,6 +554,12 @@ struct ComClient(DVersion, ComVersion = IDispatch) {
|
||||||
&argError // arg error
|
&argError // arg error
|
||||||
);//, "Invoke");
|
);//, "Invoke");
|
||||||
|
|
||||||
|
static if (args.length) {
|
||||||
|
foreach (ref v; vargs[]) {
|
||||||
|
VariantClear(&v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
if(FAILED(hr)) {
|
if(FAILED(hr)) {
|
||||||
if(hr == DISP_E_EXCEPTION) {
|
if(hr == DISP_E_EXCEPTION) {
|
||||||
|
@ -620,11 +634,87 @@ VARIANT toComVariant(T)(T arg) {
|
||||||
ret.vt = 8;
|
ret.vt = 8;
|
||||||
import std.utf;
|
import std.utf;
|
||||||
ret.bstrVal = SysAllocString(toUTFz!(wchar*)(arg));
|
ret.bstrVal = SysAllocString(toUTFz!(wchar*)(arg));
|
||||||
|
} else static if (is(T : E[], E)) {
|
||||||
|
auto sizes = ndArrayDimensions!uint(arg);
|
||||||
|
SAFEARRAYBOUND[sizes.length] saBound;
|
||||||
|
foreach (i; 0 .. sizes.length) {
|
||||||
|
saBound[i].lLbound = 0;
|
||||||
|
saBound[i].cElements = sizes[i];
|
||||||
|
}
|
||||||
|
enum vt = vtFromDType!E;
|
||||||
|
SAFEARRAY* sa = SafeArrayCreate(vt, saBound.length, saBound.ptr);
|
||||||
|
int[sizes.length] indices;
|
||||||
|
void fill(int dim, T)(T val) {
|
||||||
|
static if (dim >= indices.length) {
|
||||||
|
static if (vt == VARENUM.VT_BSTR) {
|
||||||
|
import std.utf;
|
||||||
|
SafeArrayPutElement(sa, indices.ptr, SysAllocString(toUTFz!(wchar*)(val)));
|
||||||
|
} else {
|
||||||
|
SafeArrayPutElement(sa, indices.ptr, &val);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
foreach (i; 0 .. val.length) {
|
||||||
|
indices[dim] = cast(int) i;
|
||||||
|
fill!(dim + 1)(val[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fill!(0)(arg);
|
||||||
|
ret.vt = VARENUM.VT_ARRAY | vt;
|
||||||
|
ret.parray = sa;
|
||||||
} else static assert(0, "Unsupported type (yet) " ~ T.stringof);
|
} else static assert(0, "Unsupported type (yet) " ~ T.stringof);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns: for any multi-dimensional array, a static array of `length` values for each dimension.
|
||||||
|
/// Strings are not considered arrays because they have the VT_BSTR type instead of VT_ARRAY
|
||||||
|
private auto ndArrayDimensions(I, T)(T arg) {
|
||||||
|
static if (!is(T : const(char)[]) && (is(T == E[], E) || is(T == E[n], E, int n))) {
|
||||||
|
alias A = typeof(ndArrayDimensions!I(arg[0]));
|
||||||
|
I[1 + A.length] res = 0;
|
||||||
|
if (arg.length != 0) {
|
||||||
|
auto s = ndArrayDimensions!I(arg[0]);
|
||||||
|
res[1 .. $] = s[];
|
||||||
|
}
|
||||||
|
res[0] = cast(I) arg.length;
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
I[0] res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest {
|
||||||
|
auto x = new float[][][](2, 3, 5);
|
||||||
|
assert(ndArrayDimensions!uint(x) == [2, 3, 5]);
|
||||||
|
short[4][][5] y;
|
||||||
|
y[0].length = 3;
|
||||||
|
assert(ndArrayDimensions!uint(y) == [5, 3, 4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get VARENUM tag for basic type T
|
||||||
|
private template vtFromDType(T) {
|
||||||
|
static if (is(T == short)) {
|
||||||
|
enum vtFromDType = VARENUM.VT_I2;
|
||||||
|
} else static if(is(T == int)) {
|
||||||
|
enum vtFromDType = VARENUM.VT_I4;
|
||||||
|
} else static if (is(T == float)) {
|
||||||
|
enum vtFromDType = VARENUM.VT_R4;
|
||||||
|
} else static if (is(T == double)) {
|
||||||
|
enum vtFromDType = VARENUM.VT_R8;
|
||||||
|
} else static if(is(T == bool)) {
|
||||||
|
enum vtFromDType = VARENUM.VT_BOOL;
|
||||||
|
} else static if (is(T : const(char)[])) {
|
||||||
|
enum vtFromDType = VARENUM.VT_BSTR;
|
||||||
|
} else static if (is(T == E[], E)) {
|
||||||
|
enum vtFromDType = vtFromDType!E;
|
||||||
|
} else {
|
||||||
|
static assert(0, "don't know VARENUM for " ~ T.stringof);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If you want to do self-registration:
|
If you want to do self-registration:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue