将c dll中的变量返回到macos上的Excel VBA

siotufzp  于 2023-04-05  发布在  Mac
关注(0)|答案(1)|浏览(151)

在Paulo Bueno的项目https://github.com/buenop/MinXL中,他从C++ dll返回一个Variant,例如:

Declare PtrSafe Function IncrementArrayBy _
Lib "/Library/Application Support/Microsoft/YourLibrary.dylib" _
(ByRef v as Variant, ByVal d as Double) As Variant

我想做同样的事情,但在C.这里是我的减少代码到目前为止:
x一个一个一个一个x一个一个二个x
目前,这两个函数都向VBA返回了一个Empty。这是有意义的,就像我从回答前几个(即Vt为0)中查看16个字节一样,例如使用此代码。

Private Declare PtrSafe Sub memcpy _
Lib "/usr/lib/libSystem.dylib" _
(ByVal dest As LongPtr, ByVal src As LongPtr, ByVal count As Long)

Function peekMem(ptr As LongPtr, size As Long) As Byte()
    ReDim answer(1 To size) As Byte
    memcpy VarPtr(answer(1)), ptr, size
    peekMem = answer
End Function

Sub testVar()
    Dim fred As Variant, joe As Variant, p As LongPtr

    fred = 1#
    joe = peekMem(VarPtr(fred), 16)

    p = jinni_new_VT_DOUBLE_PTR2(5#)
    joe = peekMem(VarPtr(fred), 16)   ' this has the correct values is it

    fred = jinni_new_VT_DOUBLE_PTR(5#)
    joe = peekMem(VarPtr(fred), 16)   ' but this doesn't

    fred = jinni_new_VT_DOUBLE(5#)
    joe = peekMem(VarPtr(fred), 16)   ' and neither does this

End Sub

任何想法如何让这个工作?是vba期待一个变体**?
我并不想把数据复制到一个预先分配的变量中,因为我喜欢在堆栈上返回一个变量的简单性。
Paulo确认他返回了堆栈上的变量,将问题简化为,为什么下面的变量显示为16个零?

VARIANT2 doubleInVariant(double x, VARIANT2 * out) {
    VARIANT2 answer;
    answer.vt = VT_R8;
    answer.data.dblVal = x;
    memcpy(out, &answer, sizeof(VARIANT2));
    return answer;
}

Private Declare PtrSafe Function jinni_doubleInVariant _
Lib "/Library/Application Support/Microsoft/jinni.dylib" Alias "doubleInVariant" _
(ByVal x As Double, ByRef cpy As Variant) As Variant

Paulo指出,变量是24字节而不是16字节。因此将变量结构体更改为:

typedef struct {
    VARTYPE vt;
    WORD    wReserved1;
    WORD    wReserved2;
    WORD    wReserved3;
    union {
        DOUBLE       dblVal;
    } data;
     WORD padding[4];                // due to __VARIANT_NAME_4 in the tagVARIANT struct
} VARIANT2;

现在一切都正常了-请参阅https://github.com/coppertop-bones/jinni以获取src代码和示例电子表格。

g2ieeal7

g2ieeal71#

定义VARIANT时,使用额外的填充将结构从16字节变为24字节。

typedef struct {
    VARTYPE vt;
    WORD    wReserved1;
    WORD    wReserved2;
    WORD    wReserved3;
    union {
        DOUBLE       dblVal;
    } data;
     WORD padding[4];                // due to __VARIANT_NAME_4 in the tagVARIANT struct
} VARIANT2;

我感觉自己有点像个学生,但快速搜索的结果似乎表明,16字节是一个常见的误解。

相关问题