2017-04-25 59 views
-1

我有一个C#代码,我必须用Java重写。 方法在DLL中。JNA C结构到Java

结果

OK = 0, 
ERR_GENERAL = 1,   
ERR_INVALID_HANDLE = 5,   
ERR_OUT_OF_MEMORY = 11, 
ERR_OPERATION_NOT_ALLOWED = 12, 
ERR_OPERATION_NOT_SUPPORTED = 13, 
ERR_BUFFER_TOO_SMALL = 14 

C#代码

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
     public struct jobInfo 
     { 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] 
      public string Atr; 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] 
      public string JobName; 
      [MarshalAs(UnmanagedType.I1)] 
      public bool IsSupported; 
      public int Status; 


     } 

public static extern int search(string atr, out int job); 
public static extern int getInfo(int job, ref JobInfo jobInfo); 

int result=0; 
int job=0; 
result = search(null, out job); // result=0 
JobInfo info=new JobInfo(); 
result=getInfo(job,ref info); // result=0 
//info.Atr=354BBG 
//info.JobName=Java developer 
//info.IsSupported=true 
//info.Status=active 

招聘信息

public class JobInfo extends Structure { 
     public String Atr; 
     public String JobName; 
     public boolean IsSupported; 
     public long Status; 


     public JobInfo() { 

     } 

     public JobInfo(Pointer pointer) { 
      super(pointer); 
     } 

     public static class ByReference extends JobInfo implements Structure.ByReference { 
      public ByReference() { 
      } 

      public ByReference(Pointer p) { 
       super(p); 
       read(); 
      } 

     } 

     public static class ByValue extends JobInfo implements Structure.ByValue { 
      public ByValue() { 
      } 

      public ByValue(Pointer p) { 
       super(p); 
       read(); 
      } 

     } 

     @Override 
     protected List<String> getFieldOrder() { 
      return Arrays.asList(new String[] { "Atr", "JobName", "IsSupported", "Status" }); 
     } 

Java代码

public int search(String atr, IntByReference card); 

    public int getInfo(long card, ByReference jobInfo); 

    int result=0; 
    IntByReference job = new IntByReference(0); 
    result = Native.search(null, job); // result=0 
    JobInfo.ByReference info = new JobInfo.ByReference(); 
    result = Native.getInfo(job, info); // result=5 

我试过info.getPointer(),我试着通过new PointerByReferencegetJob(),但结果总是5(ERR_INVALID_HANDLE)。

C代码

typedef void* Job; 
typedef unsigned long int JOBLong; 

struct JobInfo 
    { 
     char  Atr[64];    
     char  JobName[64];  
     bool  IsSupported;   
     JOBLong  Status;    
    }; 


    FUNCTION(search) 
    (
     char  atr[64],  
     Job*  Job 
    ); 

    FUNCTION(getInfo) 
    (
     Job  job,  
     JobInfo* jobInfo  
    ); 

我有其他的方法,但我会问他们一个问题,如果我设法解决这个问题。

编辑:

如果我不喜欢这样

Pointer job; 
PointerByReference handle = new PointerByReference(); 
result = Native.search(null, handle);    
job = handle.getValue(); 
JobInfo info = new JobInfo(); 
result = Native.getInfo(job, info.getPointer()); // result=0 

结果是0,但信息字段为空

+0

为什么在Java方法中使用'long' d eclaration,但在C#中'int'?尺寸很重要。 – cubrr

+0

Bacause如果我使用int我得到12(ERR_OPERATION_NOT_ALLOWED) – user7918877

+0

你应该匹配C代码,而不是C#代码。使你的'Atr'和'JobName'变量'byte []'数组初始化到正确的长度。你不会告诉我们你在哪里定义了JobLong。为JobInfo声明'ByReference'映射是不必要的,传递给函数的结构会被自动视为一个指针。 –

回答

0

我已经改变了字符串字段成字节数组,现在它的工作原理

public class JobInfo extends Structure { 
    public byte[] Atr=new byte[64]; 
    public byte[] JobName=new byte[64]; 
    public int IsSupported; 
    public int Status;  

    public JobInfo() {} 

@Override 
protected List<String> getFieldOrder() { 
    return Arrays.asList(new String[] { "Atr", "JobName", "IsSupported", "Status" }); 
     } 
    }