JNA中的未知源错误(C中的返回结构数组函数)

时间:2015-06-12 11:34:59

标签: java c struct jna

我尝试制作JNA应用程序。但是,我无法从C获得sturct数组。我在java方面遇到错误( com.sun.Proxy。$ Proxy0.fill(未知来源)

这是我在下面的c代码中的一部分。我编译为共享库,我可以使用其他功能。只是在我调用fill函数时给出错误。

typedef struct A{
    double Value;
    char Type; 
    char Name[100];
    char SymbolTableName[100];
    int updateMode;
    int dataType;
    char ulSize;
} A;

typedef struct B{
    int numAs;
    struct A* as;
} B;

B fill(void){   
    B sVal;
    sVal.numAs=100;
    int i=0;
    sVal.as = (A*)malloc(sizeof(A) * sVal.numAs);
    memset(sVal.as, 0, sizeof(A) * sVal.numAs);
    //X in scope , everything is ok here.
    X= ReadShared(); // It return struct array , X is struct same type.
    for(i=0; i<sVal.numAs; i++)
    {
        sVal.as[i].Value=X->datas[i].Value; 
        sVal.as[i].Type=X->datas[i].Type;
        strcpy(sVal.as[i].Name,X->datas[i].Name);
        strcpy(sVal.as[i].SymbolTableName,X->datas[i].SymbolTableName);
        sVal.as[i].updateMode=X->datas[i].updateMode;   
        sVal.as[i].dataType=X->datas[i].dataType;   
        sVal.as[i].ulSize=X->datas[i].ulSize;           
    }
    return sVal;

}

这是我在下面的Java部分。

public class TestClass {

    public interface Test extends Library {

        public static class A extends Structure {
            public static class ByReference extends A implements Structure.ByReference{}
            double Value;
            char Type; 
            char Name;
            char SymbolTableName;
            int updateMode;
            int dataType;
            char ulSize;

            protected List getFieldOrder() {
                // TODO Auto-generated method stub
                return null;
            }
        }

        public static class B extends Structure {
            public static class ByValue extends B implements Structure.ByValue {}

            public int numAs;
            public A.ByReference as;
            protected List getFieldOrder() {
                // TODO Auto-generated method stub
                return null;
            }
        }

        public B.ByValue fill();
    }

    /**
     * @param args
     */
    public   TestClass(){

    }
    static void funcc(){
        NativeLibrary.addSearchPath("tester", "/root/Desktop/");//Path is true
        Test test=(Test)Native.loadLibrary("tester", Test.class);
        Test.B.ByValue jig=test.fill();

        Test.A[] Avals = (Test.A[])jig.as.toArray(jig.numAs);
    }
}

我如何更正此错误?为什么会这样?也许有些东西缺少什么(看不见的东西)(Java方面或c方面)。感谢您的帮助。

  

在com.sun.jna.Structure.getFields(Structure.java:911)at   com.sun.jna.Structure.deriveLayout(Structure.java:1058)at   com.sun.jna.Structure.calculateSize(Structure.java:982)at   com.sun.jna.Structure.calculateSize(Structure.java:949)at   com.sun.jna.Structure.allocateMemory(Structure.java:375)at   com.sun.jna.Structure。(Structure.java:184)at   com.sun.jna.Structure。(Structure.java:172)at   com.sun.jna.Structure。(Structure.java:159)at   com.sun.jna.Structure。(Structure.java:151)at   MyTest.TestClass $ Test $ B.(TestClass.java:38)at   MyTest.TestClass $ Test $ B $ ByValue。(TestClass.java:39)at   sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)     在   sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)     在   sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)     at java.lang.reflect.Constructor.newInstance(Constructor.java:526)     在java.lang.Class.newInstance(Class.java:379)at   com.sun.jna.Structure.newInstance(Structure.java:1651)at   com.sun.jna.Function.invoke(Function.java:408)at   com.sun.jna.Function.invoke(Function.java:315)at   com.sun.jna.Library $ Handler.invoke(Library.java:212)at    com.sun.proxy。$ Proxy0.fill(未知来源) at at   MyTest.TestClass.funcc(TestClass.java:63)at   MyTest.t7500.doGet(t7500.java:51)at   javax.servlet.http.HttpServlet.service(HttpServlet.java:621)at at   javax.servlet.http.HttpServlet.service(HttpServlet.java:722)at at   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)     在   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)     在   org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)     在   org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)     在   org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)     在   org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)     在   org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)     在   org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)     在   org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)     在   org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)     在   org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)     在   org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process(Http11Protocol.java:188)     在   org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process(Http11Protocol.java:166)     在   org.apache.tomcat.util.net.JIoEndpoint $ SocketProcessor.run(JIoEndpoint.java:302)     在   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)     在   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:615)     在java.lang.Thread.run(Thread.java:745)

1 个答案:

答案 0 :(得分:0)

You haven't defined the order of structure fields within your Structure classes. JNA needs this information in order to properly read and write from native memory.

You have also incorrectly mapped native char and char[].

For class A, you need this:

double Value;
byte Type; 
byte[] Name = new byte[100];
byte[] SymbolTableName = new byte[100];
int updateMode;
int dataType;
byte ulSize;

protected List getFieldOrder() {
    return Arrays.asList("Value", "Type", "Name", "SymbolTableName", "updateMode", "dataType", "ulSize");
}

For class B, you need this:

protected List getFieldOrder() {
    return Arrays.asList("numAs", "as");
}