简体   繁体   English

如何将结构的结构包含数组从vba传递到c-dll

[英]How to pass struct containg arrays of structs from vba to c-dll

I am trying to pass a rather large struct, containg several nested structs, to a c-dll via vba. 我试图通过vba将相当大的结构(包含几个嵌套结构)传递给c-dll。

I can do this just fine as long as there are no nested structs. 只要没有嵌套结构,我就可以做到这一点。 However, introducing the arrays of additional structs into the main struct is not working. 但是,将其他结构的数组引入主结构是行不通的。 I use visual studio 2015 and I have used "attach to process" to see what is going on inside the dll. 我使用Visual Studio 2015,并使用“附加处理”功能查看dll中发生了什么。 The first five variables in WL400PoliseRiskInn (the main struct) are passed just fine, but inside the array "dekninger" something goes bad. WL400PoliseRiskInn(主结构)中的前五个变量传递得很好,但是在数组“ dekninger”内部有些问题。

在此处输入图片说明

Everything down to, and including, "antallDekninger" is correct, but as soon as we look into the nested types, things are not as they should be. 直到“ antallDekninger”(包括“ antallDekninger”)的所有内容都是正确的,但是一旦我们研究了嵌套类型,事情就不应该如此。 The variable "alder" has the value that should be contained in "riskOpphoerAlder", and everything else seem to be out of sync. 变量“ alder”具有应包含在“ riskOpphoerAlder”中的值,其他所有内容似乎都不同步。 "rider" should be 1 and "crtable" should be "DS30". “ rider”应为1,“ crtable”应为“ DS30”。 I assume there some sort of offset once we step into the array. 我假设一旦我们进入数组,就会有某种偏移。

I have checked and double checked that my type definitions in vba match my c-structs, and as far as i can tell, they do. 我检查并再次检查了vba中的类型定义是否与我的c结构匹配,据我所知,它们确实匹配。 Am I missing something here? 我在这里想念什么吗? Do i have to do something magical in my array declarations in VBA. 我必须在VBA中的数组声明中做一些神奇的事情吗? I really don't want to tamper with my c-declarations as they are used in the c-dll, and i dont want to write another c-struct and copy from that one (reuse and all that..) 我真的不想篡改c-dll中使用的c声明,也不想编写另一个c结构并从该c复制中复制(重复使用以及所有这些..)

My vba definitions are like this 我的VBA定义是这样的

Type WL400Lext
    lextno As Long
    prosentTillegg As Long
    promilleTillegg As Long
    risikosum As Long
    datoOpphoer As String * 11
End Type

Type WL400DekningRiskInn
    rider As Long
    crtable As String * 5
    kjoenn As Byte
    alder As Long
    riskOpphoerAlder As Long
    sumins As Long
    royker As Byte
    karens As Long
    yrkesfaktor As Double
    antallLext As Long
    L400Lext(0 To 4) As WL400Lext
End Type

Type WL400PoliseRiskInn
    chdrnum As Long
    cnttype As String * 4
    datoBeregning As String * 11
    datoTegning As String * 11
    antallDekninger As Long
    dekninger(0 To 12) As WL400DekningRiskInn
    wrapstatus As Long
 End Type

And in the recieving end I have the corresponding c-types 在接收端,我有对应的c型

 typedef struct
 {
     int lextNo;
     int prosentTillegg;
     int promilleTillegg;
     int risikosum;
     char datoOpphoer[11];
 } WL400Lext;

 typedef struct
 {
     int rider;
     char crtable[5];
     char kjoenn;
     int alder;
     int riskOpphoerAlder
     int sumins;
     char royker;
     int karens;
     double yrkesfaktor;
     int iAntallLext;
     WL400Lext l400Lext[5];
} WL400DekningRiskInn;

typedef struct
{
    int chdrnum;
    char cnttype[4];
    char datoBeregning[11];
    char datoTegning[11];
    int antallDekninger;
    WL400DekningRiskInn dekninger[13];
    int wrapstatus;
} WL400PoliseRiskInn;

The calling code in vba looks like this vba中的调用代码如下所示

Public Declare Function dllBerL400PoliseRisk Lib "WinL400DLL" (polise As WL400PoliseRiskInn) As Long

Function berPoliseRisk(rngPolise As Range, rngDekninger As Range, rngLext As Range) As Long

    //lots of stuff here to fill the struct

    //Call the dll by reference   
    dllBerL400PoliseRisk polise

    //Return dummy for now whilst sorting things out :|
    berPoliseRisk = 3

End Function

I assign to the single byte values like so 我这样分配给单字节值

Dim kjoenn as String
dekning.kjoenn = Asc(kjoenn)

And the strings like so 像这样的弦

Dim crtable as String
dekning.crtable = crtable & Chr(0)

Where crtable is of length 4 (5 total with Chr(0)) crtable的长度为4(Chr(0)总共为5)

And the corresponding code in c is 并且c中的对应代码是

__declspec(dllexport) int _stdcall dllBerL400PoliseRisk(WL400PoliseRiskInn *wL400PoliseRiskInn)
{
    //Do stuff
}

A colleague and I looked a bit more into it and it turns out this is already answered in this thread Accessing a nested structure in C++ from VBA . 我和一位同事对此进行了深入研究,结果发现该问题已在此线程中得到了解决从VBA访问C ++中的嵌套结构 Argut's answer solved it! 阿古特的答案解决了!

That is... the trick is to introduce 那就是...诀窍是介绍

#pragma pack(4)

//All the c declarations

#pragma pack()

in the header file declaring the c-structs 在头文件中声明c结构

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM