日期:2014-05-20  浏览次数:21311 次

jna中传递结构体数组问题
问题描述:在java程序中传递单个结构体时,程序正常; 但是传递的参数为结构体数组时,程序出错。
提示: java.lang.IllegalArgumentException: Structure array elements must use contiguous memory (bad backing address at Structure array index 1)

具体代码如下:
dlljna2.h
C/C++ code
#define MYLIBAPI  extern   "C"     __declspec( dllexport ) 
#define CLIENT_INPUT_SIZE 4
struct UserStruct{
   long id;
   wchar_t*  name;
   int age;

};
MYLIBAPI void sayUser(UserStruct* pUserStruct);


dlljna2.cpp
C/C++ code

#include "stdafx.h"
#include "dlljna2.h"
#include "iostream"

void sayUser(UserStruct* pUserStruct){

   std::wcout.imbue(std::locale("chs"));

   std::wcout<<L"ID:"<<pUserStruct->id<<std::endl;

   std::wcout<<L"姓名:"<<pUserStruct->name<<std::endl;

   std::wcout<<L"年龄:"<<pUserStruct->age<<std::endl;

}



TestDll1Service.java
Java code

package test.cn;

import test.cn.TestDll1Service.TestDll1.UserStruct;
import com.sun.jna.Library;
import com.sun.jna.NativeLong;
import com.sun.jna.Structure;
import com.sun.jna.Native;
import com.sun.jna.WString;
public class TestDll1Service {
    public final static  int CLIENT_INPUT_SIZE = 4;

    public interface TestDll1 extends Library {
        TestDll1 INSTANCE = (TestDll1) Native.loadLibrary("dlljna2",
                TestDll1.class);
        public void say(WString value);

        public static class UserStruct extends Structure {
            public NativeLong id;
            public WString name;
            public int age;
        }

        public void sayUser(UserStruct struct);
    }

    public TestDll1Service() {
    }

    public static void main(String[] args) {
        UserStruct userStruct = new UserStruct();
        userStruct.id = new NativeLong(100);
        userStruct.age = 30;
        userStruct.name = new WString("沈东良");
        TestDll1.INSTANCE.sayUser(userStruct);
    }
}



此时java程序运行正常


但是我稍作改动dlljna2.cpp文件改为
C/C++ code

#include "stdafx.h"
#include "dlljna2.h"
#include "iostream"

void sayUser(UserStruct* pUserStruct){

   std::wcout.imbue(std::locale("chs"));

  for(int i = 0; i < CLIENT_INPUT_SIZE; i++)
   {
       std::wcout<<L"ID:"<<pUserStruct[i].id<<std::endl;

   std::wcout<<L"姓名:"<<pUserStruct[i].name<<std::endl;

    std::wcout<<L"年龄:"<<pUserStruct[i].age<<std::endl;
}




然后将TestDll1Service.java代码改为
Java code

package test.cn;
import test.cn.TestDll1Service.TestDll1.UserStruct;
import com.sun.jna.Library;
import com.sun.jna.NativeLong;
import com.sun.jna.Structure;
import com.sun.jna.Native;
import com.sun.jna.WString;

public class TestDll1Service {
    public final static  int CLIENT_INPUT_SIZE = 4;
    public interface TestDll1 extends Library {
        TestDll1 INSTANCE = (TestDll1) Native.loadLibrary("dlljna2",
                TestDll1.class);

        public void say(WString value);

        public static class UserStruct extends Structure {
            public NativeLong id;
            public WString name;
            public int age;
        }

        public void sayUser(UserStruct[] struct);
    }

    public TestDll1Service() {
    }

    public static void main(String[] args) {
        UserStruct[] userStructs = new UserStruct[CLIENT_INPUT_SIZE];
        
        for(int i = 0; i < CLIENT_INPUT_SIZE; i++)
        {
            userStructs[i] =new UserStruct();
            userStructs[i].id = new NativeLong(100);
            userStructs[i].age = 30;
            userStructs[i].name = new WString("沈东良");
        }
        TestDll1.INSTANCE.sayUser(userStructs);
    }
}