2017-03-20 68 views
0

我想通過vba將一個相當大的結構,包含幾個嵌套的結構,傳遞給c-dll。如何將結構包含vba的結構數組傳遞給c-dll

只要沒有嵌套的結構體,我就可以做到這一點。但是,將附加結構的數組引入主結構不起作用。我使用visual studio 2015,並使用「附加到進程」來查看dll內部發生了什麼。 WL400PoliseRiskInn(主結構體)中的前五個變量傳遞得很好,但在數組「dekninger」內部發生了一些變化。

enter image description here

一切都落下來,和包括「antallDekninger」是正確的,但只要我們看看到嵌套類型,事情並不像他們應該。變量「alder」具有應該包含在「riskOpphoerAlder」中的值,而其他一切似乎都不同步。 「騎手」應該是1,「crtable」應該是「DS30」。一旦我們進入數組,我假設有一些偏移量。

我已經檢查並仔細檢查過我的vba中的類型定義是否與我的c-structs匹配,並且據我所知,它們的確如此。我在這裏錯過了什麼嗎?我需要在VBA中的數組聲明中做些神奇的事情嗎?我真的不想篡改我的c聲明,因爲它們在c-dll中使用,我不想寫另一個c-struct和從那個複製(重用和所有..)

我的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 

而在recieving我到底有相應的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; 

在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 

我分配給單個字節值,像這樣

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

和琴絃像這樣

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

哪裏crtable是長度4(5總與CHR(0))

的並且c中的相應代碼是

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

VBA字符串是寬字符,所以你的結構聲明不匹配。 – Comintern

+0

嗯..可愛。但是,這是什麼意思?主結構包含幾個char數組,它們被讀取得很好。不匹配在哪裏? – mortysporty

+1

究竟發生了什麼,我不知道,但在VBA中,'cnttype As String * 4'的寬度爲8個字節,'char cnttype [4];'不是。它可能只是嵌套類型編組的一個怪癖,但是你可以嘗試在VBA聲明中使用字節數組,以便它們*不能*不對齊。 – Comintern

回答

0

一個同事和我看起來更多一點,事實證明這已經在這個線程Accessing a nested structure in C++ from VBA回答。阿古特的答案解決了它!

也就是說,祕訣是在頭文件中介紹

#pragma pack(4) 

//All the c declarations 

#pragma pack() 

宣佈C-結構