我试图弄清楚如何将用户定义的结构从VB6应用程序传递到C++ DLL。

这是我的VB6代码的示例:

Private Type ObjetVB
    Rank As Integer
    Id As String
End Type

Private Declare Sub testLObj Lib "D:\TestDLL.dll" (Tab_Obj() As ObjetVB)
Private Declare Sub testObj Lib "D:\TestDLL.dll" (ByRef Obj As ObjetVB)

Private Sub Command1_Click()
    Dim elements(1 To 4) As ObjetVB, i As Long

    For i = 1 To 4
        elements(i).Rank = i
        elements(i).Id = "Pouet"
    Next

    testLObj elements()
End Sub

Private Sub Command2_Click()
    Dim ObjCrash As ObjetVB

    ObjCrash.Rank = 1
    ObjCrash.Id = "Pouet"

    testObj ObjCrash

End Sub

还有我的C++代码示例:
struct ObjetVB
{
    short Rank;
    char* Id;
};

void videFichier()
{
    ofstream fichier("../../../log.txt", ios::out | ios::trunc);
    if(fichier)
    {
        fichier.close();
    }
}

int Log(ObjetVB ObjInput)
{
    ofstream fichier("../../../log.txt", ios::out | ios::app);
    if(fichier)
    {
        fichier << ObjInput.Rank << endl << "Id : " << ObjInput.Id << endl << endl;
        fichier.close();
    }
    return 0;
}

void __stdcall testObj (ObjetVB* ObjInput)
{
    videFichier();
    log(*ObjInput);
}

void __stdcall testLObj (SAFEARRAY **Tab_Obj)
{
    ObjetVB *elt;
    HRESULT ret;
    unsigned long i;
    videFichier();

    if ((ret = SafeArrayAccessData(*Tab_Obj,(void **) &elt))==S_OK)
    {
        for (i = 0; i < (*Tab_Obj)->rgsabound->cElements; i++)
        {
            Log(elt[i]);
        }
        SafeArrayUnaccessData(*Tab_Obj);
    }
}

我的问题是,当我单击“Command2”时,我的日志文件如下所示:
1
Id : Pouet

而当我单击“Command1”时,它看起来像这样:
1
Id : P

2
Id : P

3
Id : P

4
Id : P

为什么当我传递单个项目时,我的C++ DLL为什么将“char * Id”识别为字符链,而当我使用一系列项目时,它看起来像将其识别为指向第一个字符的指针?

而且,最值得注意的是,我该如何解决?我尝试在我的c++结构中使用LBSTR而不是char *,但并没有解决它,我还尝试在初始化VB6字符串之前添加“elements(i).Id = String(255,vbNullChar)”,但它没有事实证明也没有帮助。

和往常一样,我要感谢你们所有人投入阅读和提供帮助的时间。

附带一提:英语对我来说是一种外国语言,所以我希望我几乎可以理解,当然,如果不是这样,我深表歉意。

编辑:

我不知道是否有帮助,但是尝试了Mark Bertenshaw的建议之后,我也尝试了以下方法:
在VB6中:
Id As String * 10

在C++中:
char Id[10];

这给了这个奇怪的结果:
Objet :
32
Id : P

Objet :
1
Id :

Objet :
32
Id : P

Objet :
2
Id :

最佳答案

VB6返回一个BSTR而不是一个char数组。一个BSTR将充满宽字符。我相信,对于标准的罗马字母,2字节编码与ASCII相同,但是第二个字节为0,因此您的字符串似乎具有零长度。

您可以使用wchar_t *代替char *,您会发现一切似乎正常。尽管您不能保证wchar_t和BSTR的大小相同,但这并不是最好的方法。

最好的选择是使用ConvertBSTRToString函数。

10-02 02:33
查看更多