当前位置:编程学习 > VB >>

从C++ DLL中获取结构数组问题.

C++的DLL部分定义如下:
typedef char DBITBLNAME [261];
typedef char DBINAME    [32]; 

#ifndef UINT16
#if defined(__FLAT__)
#  define UINT16  unsigned short
#else
#  define UINT16  unsigned int
#endif // defined(__FLAT__)
#endif // UINT16

#ifndef INT16
#if defined(__FLAT__)
#  define INT16   short
#else
#  define INT16   int
#endif // defined(__FLAT__)
#endif // INT16

typedef struct {
      DBITBLNAME     szName;                 
      UINT16         iFNameSize;             
      DBINAME        szTableType;            
      UINT16         iFields;                
      UINT16         iRecSize;               
      UINT16         iRecBufSize;            
      UINT16         iKeySize;               
      UINT16         iIndexes;               
      UINT16         iValChecks;             
      UINT16         iRefIntChecks;          
      UINT16         iBookMarkSize;          
      short          bBookMarkStable;        
      DBIOpenMode    eOpenMode;              
      DBIShareMode   eShareMode;             
      short          bIndexed;               
      INT16          iSeqNums;               
                                             
      short          bSoftDeletes;           
      short          bDeletedOn;             
      UINT16         iRefRange;              
      XLTMode        exltMode;               
      UINT16         iRestrVersion;          
      short          bUniDirectional;        
      PRVType        eprvRights;             
      UINT16         iFmlRights;             
      UINT16         iPasswords;             
      UINT16         iCodePage;              
      short          bProtected;             
      UINT16         iTblLevel;              
      DBINAME        szLangDriver;           
      short          bFieldMap;              
      UINT16         iBlockSize;             
      short          bStrictRefInt;          
      UINT16         iFilters     ;          
      short          bTempTable   ;          
      UINT16         iUnUsed[16];
     } CURProps;
typedef CURProps far *pCURProps;

DBIResult DBIFN DbiGetCursorProps (
      hDBICur        hCursor,           
      pCURProps      pcurProps          
    );


VB调用部分代码如下:
Public Type CURProps
    szName(1 To 261) As Byte           
    iFNameSize As Integer                               
    szTableType(1 To 32) As Byte         
    iFields As Integer                                  
    iRecSize As Integer                                 
    iRecBufSize As Integer                              
    iKeySize As Integer                                 
    iIndexes As Integer                                 
    iValChecks As Integer                               
    iRefIntChecks As Integer                            
    iBookMarkSize As Integer                            
    bBookMarkStable As Integer                          
    eOpenMode As DBIOpenMode                            
    eShareMode As DBIShareMode                          
    bIndexed As Integer                                 
    iSeqNums As Integer                                 
                                                        
    bSoftDeletes As Integer                             
    bDeletedOn As Integer                               
    iRefRange As Integer                                
    exltMode As XLTMode                                 
    iRestrVersion As Integer                            
    bUniDirectional As Integer                          
    eprvRights As PRVType                               
    iFmlRights As Integer                               
    iPasswords As Integer                               
    iCodePage As Integer                                
    bProtected As Integer                               
    iTblLevel As Integer                                
    szLangDriver(1 To 32) As Byte        
    bFieldMap As Integer                                
    iBlockSize As Integer                               
    bStrictRefInt As Integer                            
    iFilters As Integer                                 
    bTempTable As Integer                               
    iUnUsed(1 To 16) As Integer
End Type

Public Declare Function DbiGetCursorProps Lib "IDAPI32.dll" (ByVal hcursor As Long, pcurProps As CURProps) As Integer

运行后发现. CURProps结构中, 数据不对. iFields应该是Field Count, 明明表中只有10个Field, 但得到的数据却是32256. 结构中其他field数据也都不正常, 怀疑是VB对此结构体的定义与C++中的没有对齐, 但实在是找不出哪儿有问题. 请高手赐教! 急等. 多谢了. --------------------编程问答-------------------- szName(1   To   261)   As   Byte        改为262试试看 后面会有1字节填充的. --------------------编程问答-------------------- to akirya:
    感谢你的回复, 这样也是得不到正确结果的.  --------------------编程问答-------------------- 你先检查下字节对齐了吗?你还有几个结构没贴出来 --------------------编程问答-------------------- 先把所用的结构都贴全了,然后传递一个看看,看看在那几个变量是不正确的. --------------------编程问答-------------------- .......好象没啥好说的了.... --------------------编程问答-------------------- C中的DBIOpenMode、DBIShareMode等如何定义?
在C中取得sizeof(CURProps),与VB中的Len(pcurProps)比较是否一致? --------------------编程问答-------------------- sorry, 我忘记说了, DBIOpenMode、DBIShareMode等没贴出来的都是enum.
C++部分
typedef enum                                 
   {
      dbiREADWRITE      = 0,                 
      dbiREADONLY       = 1                  
   } DBIOpenMode;

typedef enum                              
   {
      dbiOPENSHARED     = 0,                 
      dbiOPENEXCL       = 1,                 
   } DBIShareMode;

typedef enum                              
   {
      xltNONE        = 0,                    
      xltRECORD      = 1,                    
      xltFIELD       = 2,                    
   } XLTMode;

typedef enum  {                            
      prvNONE        = 0,                     
      prvREADONLY    = 0x01,                  
      prvMODIFY      = 0x03,                  
      prvINSERT      = 0x07,                  
      prvINSDEL      = 0x0F,                  
      prvFULL        = 0x1F,                  
      prvUNKNOWN     = 0xFF                   
   } PRVType;

VB部分:
Public Enum DBIOpenMode
    dbiREADWRITE = 0                
    dbiREADONLY = 1                 
End Enum

Public Enum DBIShareMode
    dbiOPENSHARED = 0               
    dbiOPENEXCL = 1                 
End Enum

Public Enum XLTMode
    xltNONE = 0                     
    xltRECORD = 1                   
    xltFIELD = 2                    
End Enum

Public Enum PRVType
    prvNONE = 0                     
    prvREADONLY = &H1               
    prvMODIFY = &H3                 
    prvINSERT = &H7                 
    prvINSDEL = &HF                 
    prvFULL = &H1F                  
    prvUNKNOWN = &HFF               
End Enum

To Chenghui530:
    目前的确是怀疑未对齐, 但一时半会没找出是哪儿出了问题...

To Tiger_Zhao:
    对于C/C++, 只能看看源码...

To All:
    请各位多帮忙. 感谢. --------------------编程问答-------------------- len(结构)是否等于sizeof(结构) --------------------编程问答-------------------- to chenhui530:
    现在无法去试. 晚点试过再请教了. 谢谢了. --------------------编程问答-------------------- 注意:VB中的Enum是Long(Int32)!
你C中的enum是多少? --------------------编程问答-------------------- 注意这句:#ifndef   UINT16 
这里的意思是说:如果定义了UINT16
你看看*.h文件中有没有定义这个类型
C中int类型等于VB的Long类型
如果有的话,则变量类型为Integer,如果没有则为Long

如果枚举的话,VB只支持Long类型,所以一般是没什么问题的
--------------------编程问答-------------------- >如果枚举的话,VB只支持Long类型,所以一般是没什么问题的 
好像记得C中enum的字节数可以配置的,所以不能保证。 --------------------编程问答-------------------- 怎么不做个COM接口 --------------------编程问答-------------------- 来罐下水! --------------------编程问答-------------------- --------------------编程问答-------------------- 首先感谢大家的回复. 这个API实际上是Borland BDE Engine里的一个API, 我没有源码:). 也不可能拿到有COM接口的DLL. :p 由于手上目前没有VC++, 所以还真的试不出sizeof(CURProps)所占内存的大小, 真是头痛啊...引出这个问题的原因是, 我需要修改从第三方处获得的paradox文件的column name. 不得已需要直接调用这些API.  --------------------编程问答-------------------- to Sandrer:
UINT16的定义我在最开始已经贴出来了. 
#ifndef   UINT16 
#if   defined(__FLAT__) 
#     define   UINT16     unsigned   short 
#else 
#     define   UINT16     unsigned   int 
#endif   //   defined(__FLAT__) 
#endif   //   UINT16 
因为不太理解__FLAT__的含义, 所以只是译成了integer. 之后也有尝试过long, 但采用long会报错. --------------------编程问答-------------------- 刚刚找来个Visual Studio.Net中的VC++.Net试了一下, len(CURProps)和sizeof(CURProps)都是427. 我晕了. 哪位老大来救救命... --------------------编程问答-------------------- 友情顶一下 --------------------编程问答-------------------- --------------------编程问答-------------------- 没人解答了嘛? 很奇怪, C++和VB中定义的2个结构长度一样, C++里的enum我看过也是4个字节的. 真的是搞不懂了... --------------------编程问答-------------------- 你的DLL是用哪个编译器编的就在该编译器上进行测试,不同的C编译器有差异的。 --------------------编程问答-------------------- To Tiger_Zhao:
    这个dll是borland提供的, 事实上我也不知道是哪个编译器编译的. 我从codeproject上找到一个vc写的call这个DLL部分API的demo, 是可以正常获得数据的...之前的sizeof(CURProps)等于427也是在这个demo的环境中得到的. --------------------编程问答-------------------- 应该就是对齐的问题,如下
Sub Main()
    Dim t As CURProps, a(2 - 1) As CURProps
    Debug.Print Len(t), VarPtr(a(1)) - VarPtr(a(0))
End Sub

输出为:
 427           432


你只能用一个够大的Byte数组调用函数,然后用CopyMemory的方式逐个复制到结构中。 --------------------编程问答-------------------- To Tiger_Zhao:
    之前我是直接传一个结构地址给API的, 后来也试过声明一个427个元素的byte array, 然后用copymemory方式, 复制到结构中, 结果和直接传结构地址是一样的. 难得要逐个复制到结构的每个field里? 谢谢.
补充:VB ,  API
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,