最近使用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的转换?

解决方案 »

  1.   

    你的错误很多,我下面给你一个正确的结构体转化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方法中,将你所有属性依次按照顺序列出,这样是将所有属性转化为流输出的
      

  2.   

    我遇到了和楼主几乎一样的问题,是转换vector<string>,正在思考中,如果有人知道,希望能给予点拨,感激不尽