【急】JNA 中vector转换问题

biangjiandjibiang 2011-11-08 11:38:04
最近使用JNA封装调用C接口,但是遇到了一些问题,请大家指教
主要是结构体和vector转换问题,具体的问题如下:


结构体1:
typedef struct tagDataObjInformation
{
tagDataObjInformation()
{
memset(szMagicFlag, 0, MAGICFLAG_LEN);
iMajorVer = 2;
iMinorVer = 0;
iType = 0; //最高4bit位用来区分大类型 CURVE TABLE STREAM
memset(szName, 0, DATAOBJ_NAME_LEN);
iDimension = 0;
lLength = 0;
bDeleteTag = 0;
lModifyTime =0 ;
memset(szDescription, 0, DATAOBJ_DESCRIPTION_LEN);
};
char szMagicFlag[MAGICFLAG_LEN];
_int32 iMajorVer;
_int32 iMinorVer;
_int32 iType; //最高4bit位用来区分大类型 CURVE TABLE STREAM
char szName[DATAOBJ_NAME_LEN];
_int32 iDimension;
_int64 lLength;
BYTE bDeleteTag;
_int64 lModifyTime;
char szDescription[DATAOBJ_DESCRIPTION_LEN];
}DataObjInformation;

结构体2:
typedef struct tagCurveDimension
{
tagCurveDimension()
{
memset(szName, 0, DATAOBJ_NAME_LEN);
memset(szAlias, 0, DATAOBJ_ALIAS_LEN);
memset(szUnit, 0, DATAOBJ_UNIT_LEN);
iRepCode = 0;
iRepLen = 0;
iMaxCount = 0;
iCount = 0;
fMin = 0;
fMax = 0;
fStep = 0;
iAdi = 0;
memset(szReserved, 0, 16);
};
char szName[DATAOBJ_NAME_LEN];
char szAlias[DATAOBJ_ALIAS_LEN];
char szUnit[DATAOBJ_UNIT_LEN];
_int32 iRepCode;
_int32 iRepLen;
_int32 iMaxCount;
_int32 iCount;
float fMin;
float fMax;
float fStep;
_int32 iAdi;
char szReserved[16];
}CurveDimension;
结构体3:
typedef struct tagCurveInfo
{
DataObjInformation Info;
CurveDimension Dim[CURVE_MAX_DIMS];
}CurveInfo;

我在Java中对应的转换
结构体一
public static class DataObjInformation extends Structure{
public byte[] szMagicFlag = new byte[LeadGlobal.MAGICFLAG_LEN];//32
public int iMajorVer;
public int iMinorVer;
public int iType;
public byte[] szName = new byte[LeadGlobal.DATAOBJ_NAME_LEN];//32
public int iDimension;
public long lLength;
public byte bDeleteTag;
public long lModifyTime;
public byte[] szDescription = new byte[LeadGlobal.DATAOBJ_DESCRIPTION_LEN];//128
public byte[] szReserved = new byte[231];

public static class ByReference extends DataObjInformation implements Structure.ByReference{}
public static class ByValue extends DataObjInformation implements Structure.ByValue{}
}

结构体二
public static class CurveDimension extends Structure{
public byte[] szName = new byte[LeadGlobal.DATAOBJ_NAME_LEN]; //32
public byte[] szAlias = new byte[LeadGlobal.DATAOBJ_ALIAS_LEN];//32
public byte[] szUnit = new byte[LeadGlobal.DATAOBJ_UNIT_LEN];//32
public int iRepCode;
public int iRepLen;
public int iMaxCount;
public int iCount;
public float fMin;
public float fMax;
public float fStep;
public int iAdi;
public byte[] szReserved = new byte[16];
public static class ByReference extends CurveDimension implements Structure.ByReference{}
public static class ByValue extends CurveDimension implements Structure.ByValue{}
}
结构体三
public static class CurveInfo extends Structure{
public DataObjInformation.ByValue Info;
public CurveDimension.ByValue[] Dim = new CurveDimension.ByValue[LeadGlobal.CURVE_MAX_DIMS]; //4

public static class ByReference extends CurveInfo implements Structure.ByReference{}
public static class ByValue extends CurveInfo implements Structure.ByValue{}
}

/////////////////////////////////////////////////////////
C接口
int UFCreateCurve2(const char *szFullLogPath, const char *szCurveObjName, CurveInfo *pCurveInfo, bool bOverWriteIfExist=false);
使用JNA封装的对应的接口为:
public int UFCreateCurve2(String szFullLogPath, String szCurveObjName, CurveInfo.ByReference pCurveInfo , boolean OverWriteIfExist);

//////////////////////////////////////////////////////////
我的测试代码:
String szFullLogPath = "D:\\lead3.0.tmp\\Workspace\\#城75\\城75.gds";
String szCurveObjName = "JAVA";
CurveInfo.ByReference pCurveInfo = new CurveInfo.ByReference();

DataObjInformation.ByValue infoByValue = new DataObjInformation.ByValue();
infoByValue.szName = "JAVA".getBytes();
infoByValue.szMagicFlag = "CURVE".getBytes();
infoByValue.iType = 0x10000001;
infoByValue.szDescription = "This".getBytes();
infoByValue.write();
pCurveInfo.Info = infoByValue;

CurveDimension.ByValue Dim0 = new CurveDimension.ByValue();
Dim0.szName = "dep".getBytes();
Dim0.szAlias = "深度".getBytes();
Dim0.szUnit = "m".getBytes();
Dim0.fMin = 100f;
Dim0.fMax = 500f;
Dim0.fStep = 0.125f;
Dim0.write();

CurveDimension.ByValue Dim1 = new CurveDimension.ByValue();
Dim1.szName = "JAVA".getBytes();
Dim1.szAlias = "爪哇".getBytes();
Dim1.fMin = 0f;
Dim1.fMax = 10f;
Dim1.fStep = 1f;
Dim1.write();

pCurveInfo.Dim[0] = Dim0;
pCurveInfo.Dim[1] = Dim1;

int iCreateCurve2 = instance.UFCreateCurve2(szFullLogPath, szCurveObjName, pCurveInfo, true);
System.out.println("Create Curve2:"+iCreateCurve2);
错误:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Bounds exceeds available space : size=520, offset=728
at com.sun.jna.Memory.boundsCheck(Memory.java:149)
at com.sun.jna.Memory.share(Memory.java:90)
at com.sun.jna.Structure.useMemory(Structure.java:206)
at com.sun.jna.Structure.writeArrayValue(Structure.java:759)
at com.sun.jna.Structure.writeValue(Structure.java:704)
at com.sun.jna.Structure.writeField(Structure.java:642)
at com.sun.jna.Structure.write(Structure.java:571)
at com.sun.jna.Function.convertArgument(Function.java:410)
at com.sun.jna.Function.invoke(Function.java:206)
at com.sun.jna.Library$Handler.invoke(Library.java:204)
at $Proxy0.UFCreateCurve2(Unknown Source)
at gds.Test1.main(Test1.java:56)

问题1:测试代码中哪错了?

问题2:
C中又定义了一个结构体:
typedef CurveInfo DataObjIndexInfo;
在Java中,我这样封装:
public static class DataObjIndexInfo extends CurveInfo{}

C接口:
int UFGetAllTable(const char *szFullLogPath, vector<DataObjIndexInfo> &aInfo, const char *szTableType = NULL);

问题:
1、对于C中的typedef定义的属性,在Java中可以通过extends来实现吗?比如上面的public static class DataObjIndexInfo extends CurveInfo{}???

2、JNA如何实现vector的转换?

...全文
967 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复 1
我遇到了和楼主几乎一样的问题,是转换vector<string>,正在思考中,如果有人知道,希望能给予点拨,感激不尽
luoyuke520 2011-11-14
  • 打赏
  • 举报
回复
你的错误很多,我下面给你一个正确的结构体转化java类的实例:
public class TNetAddr extends Structure<TNetAddr, TNetAddr.ByValue, TNetAddr.ByReference > {
public NativeLong m_dwIp;
public short m_wPort;
public TNetAddr() {
super();
initFieldOrder();
}
protected void initFieldOrder() {
setFieldOrder(new java.lang.String[]{"m_dwIp", "m_wPort"});
}
public TNetAddr(NativeLong m_dwIp, short m_wPort) {
super();
this.m_dwIp = m_dwIp;
this.m_wPort = m_wPort;
initFieldOrder();
}
protected ByReference newByReference() { return new ByReference(); }
protected ByValue newByValue() { return new ByValue(); }
protected TNetAddr newInstance() { return new TNetAddr(); }
public static TNetAddr[] newArray(int arrayLength) {
return Structure.newArray(TNetAddr.class, arrayLength);
}
public static class ByReference extends TNetAddr implements Structure.ByReference {

};
public static class ByValue extends TNetAddr implements Structure.ByValue {

};
}
说明:在initFieldOrder方法中,将你所有属性依次按照顺序列出,这样是将所有属性转化为流输出的

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧