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

寒星 2007-12-28 05:40:25
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++中的没有对齐, 但实在是找不出哪儿有问题. 请高手赐教! 急等. 多谢了.
...全文
1177 25 打赏 收藏 举报
写回复
25 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
寒星 2008-01-07
To Tiger_Zhao:
之前我是直接传一个结构地址给API的, 后来也试过声明一个427个元素的byte array, 然后用copymemory方式, 复制到结构中, 结果和直接传结构地址是一样的. 难得要逐个复制到结构的每个field里? 谢谢.
  • 打赏
  • 举报
回复
Tiger_Zhao 2008-01-07
应该就是对齐的问题,如下
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的方式逐个复制到结构中。
  • 打赏
  • 举报
回复
寒星 2008-01-07
To Tiger_Zhao:
这个dll是borland提供的, 事实上我也不知道是哪个编译器编译的. 我从codeproject上找到一个vc写的call这个DLL部分API的demo, 是可以正常获得数据的...之前的sizeof(CURProps)等于427也是在这个demo的环境中得到的.
  • 打赏
  • 举报
回复
Tiger_Zhao 2008-01-07
你的DLL是用哪个编译器编的就在该编译器上进行测试,不同的C编译器有差异的。
  • 打赏
  • 举报
回复
寒星 2008-01-07
没人解答了嘛? 很奇怪, C++和VB中定义的2个结构长度一样, C++里的enum我看过也是4个字节的. 真的是搞不懂了...
  • 打赏
  • 举报
回复
寒星 2008-01-03
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会报错.
  • 打赏
  • 举报
回复
寒星 2008-01-03
首先感谢大家的回复. 这个API实际上是Borland BDE Engine里的一个API, 我没有源码:). 也不可能拿到有COM接口的DLL. :p 由于手上目前没有VC++, 所以还真的试不出sizeof(CURProps)所占内存的大小, 真是头痛啊...引出这个问题的原因是, 我需要修改从第三方处获得的paradox文件的column name. 不得已需要直接调用这些API.
  • 打赏
  • 举报
回复
mk117 2008-01-03
友情顶一下
  • 打赏
  • 举报
回复
寒星 2008-01-03
刚刚找来个Visual Studio.Net中的VC++.Net试了一下, len(CURProps)和sizeof(CURProps)都是427. 我晕了. 哪位老大来救救命...
  • 打赏
  • 举报
回复
蒋晟 2007-12-31
怎么不做个COM接口
  • 打赏
  • 举报
回复
yiming1981 2007-12-31
来罐下水!
  • 打赏
  • 举报
回复
Tiger_Zhao 2007-12-29
>如果枚举的话,VB只支持Long类型,所以一般是没什么问题的
好像记得C中enum的字节数可以配置的,所以不能保证。
  • 打赏
  • 举报
回复
Sandrer 2007-12-29
注意这句:#ifndef UINT16
这里的意思是说:如果定义了UINT16
你看看*.h文件中有没有定义这个类型
C中int类型等于VB的Long类型
如果有的话,则变量类型为Integer,如果没有则为Long

如果枚举的话,VB只支持Long类型,所以一般是没什么问题的
  • 打赏
  • 举报
回复
Tiger_Zhao 2007-12-29
注意:VB中的Enum是Long(Int32)!
你C中的enum是多少?
  • 打赏
  • 举报
回复
寒星 2007-12-29
to chenhui530:
现在无法去试. 晚点试过再请教了. 谢谢了.
  • 打赏
  • 举报
回复
chenhui530 2007-12-29
len(结构)是否等于sizeof(结构)
  • 打赏
  • 举报
回复
寒星 2007-12-29
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:
请各位多帮忙. 感谢.
  • 打赏
  • 举报
回复
Tiger_Zhao 2007-12-29
C中的DBIOpenMode、DBIShareMode等如何定义?
在C中取得sizeof(CURProps),与VB中的Len(pcurProps)比较是否一致?
  • 打赏
  • 举报
回复
.......好象没啥好说的了....
  • 打赏
  • 举报
回复
先把所用的结构都贴全了,然后传递一个看看,看看在那几个变量是不正确的.
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
API
加入

1472

社区成员

VB API
社区管理员
  • API
申请成为版主
帖子事件
创建了帖子
2007-12-28 05:40
社区公告
暂无公告