vc写的com里面有个函数返回一个自定义数组,数组里面有BSTR遍历Variant数组里的变量用copymemory的方法搞定了,但是里面有了BSTR就这样一copy连vb都崩溃了.
由于variant是从vc写的com中返回的,所以只能将就着用,com是不会修改的!所以请大家不要再建议用返回数组的方法,先谢过

解决方案 »

  1.   

    刚才试了如下情况,是可以复制的
    Private Type tagMy
        szttt As String
        nnn As Long
    End TypeDim ddf As tagMy
        Dim ddf2 As tagMy
        ddf2.szttt = "hhhh"
        CopyMemory ddf, ddf2, LenB(ddf)
        ddf2.szttt = "fffaaaaa"难道是com导出的结构体有问题??
      

  2.   

    你用oleview看看结构体是怎么定义的,我怀疑是你结构体定义的问题
      

  3.   

    这是人家给的demo工程里的结构体定义,真正的com还没给我,只是让先研究一下如何使用
    typedef enum {
        cloudy = 0,
        sunny = 23
    } CloudCover;typedef struct tagCOMPONENT_INFO2 {
    BSTR bstrName;
    CloudCover eCover;
    long bOK;
    long l;
    short s;
    } COMPONENT_INFO2;typedef struct tagCOMPONENT_INFO3 {
    COMPONENT_INFO2 info2;
    CloudCover eCover;
    long bOK;
    } COMPONENT_INFO3;
      

  4.   

    呵呵,习惯在调用API时,与LPSTR打交道,碰到BSTR真是亲切!它就是VB自己支持的自动化类型。但放在结构中,还真不敢确定怎么用它。
    为自动化类型写的Dll,按MSDN中的说法,是可以直接Byref引用的,也就是说按原结构声明一个相同类型的结构,直接交给DLL就行了。若不行,可试试以下方案:
    BSTR是以指针传递的,所以string在结构中就是一个Long指针,指向一个BSTR字符串
    你的结构应声明成Long,
    Private Type tagMy
        szttt As long
        nnn As Long
    End Type
    先copymemory出这个结构,然后,再从结构中copymemory出你的String。
    因是BSTR,所以copy这个String时不要用Byval String,而用下面形式:
    dim s1 as string,s as string
    copymemory byval varptr(s),byref tagMy.szttt,4'先用VB的String仿冒这个BSTR
    s1=s'用VB的方法复制取回BSTR
    copymemory byval varptr(s),byref 0&,4'要还原s的指针,不然VB可能会崩的
    s1是数据上面方法不一定可行,因是BSTR,在使用API时反而让VB有些难了。也许直接用VB取得,才是正路。
      

  5.   

    又定义了一个与导出结构体一致的type可以复制,不过string类型的值是ansi的,经过strconv转换就好了
    但不知为什么只能一个一个的copy,一次拷贝数量>1时还是崩溃
    但是这个方法很笨,据说那个com中导出了n个struct,不能都重新定义一遍啊!!到底问题出在哪里?
      

  6.   

    //但是这个方法很笨,据说那个com中导出了n个struct,不能都重新定义一遍啊!!没什么办法,只能这样了
      

  7.   

    BSTR是Unicode呀,只有16位程序才会是ANSI
    若是ANSI,可能是某次调用API采用了Byval传递String,这样调用VB用自动将Unicode转成ANSI。
    一次拷贝数量>1时还是崩溃
    =======================崩溃的原因,我能想到的有两种:
    1、是结构长度不对,这一点,通过验证结构第一与最后一个元素的值是否正确,即可轻易查出;
    2、就是出在String类型上,BSTR是以指针传递,用copymemory或非VB方式复制String或含有String的结构,都是不可靠且暂时的,因为VB不知道这些变化,当这些String需重置时(如:重新赋值),VB会自动释放旧数据内存,因为这部分内存非VB申请所得,所以常会出错。
    可靠一点的办法是,用VB赋值方法将Copy取得的String或结构再赋值给一个新的VB变量,然后同样用Copy方法恢复原String或结构的指针。这一点,前面回贴中已写了相关示例。
      

  8.   

    昨天试了半天1、是结构长度不对,这一点,通过验证结构第一与最后一个元素的值是否正确,即可轻易查出;
    --------------------------
    结构体的size没问题,我已经考虑了内存对齐. 
    由于问题出在一次拷贝数量>1时(即数组的复制时),所以我怀疑vb数组的相邻两个元素之间有段空白内存,但这个只是怀疑2、String问题
    ---------------------------
    这个方法感觉很复杂,如果结构体中string比较多,实现代价会很大. 但还是谢谢
      

  9.   

    VB结构里面有String时,它是个指针,memorycopy时只是copy指针,所以出错。
    homezj(小吉)的方法应该是可行的,就是先copy这个BSTR,然后再copy指针。或者考虑不用结构,直接定义一个byte()来传递参数,只是COM传的数组要知道大小,然后再拆开
      

  10.   

    //结构体的size没问题,我已经考虑了内存对齐.结构体的size是4的倍数吗?
      

  11.   

    //结构体的size是4的倍数吗?  size=28 绝对没问题!copy bstr指针的方法与我前面定义一个数组一个一个copy的方法,两者都无法避免for循环.而且感觉实现起来更加复杂!虽然没有找出最终原因,但项目还是要开展的!就这样吧,谢谢各位