jna中传递结构体数组问题

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

具体代码如下:
dlljna2.h
#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

#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

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文件改为

#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代码改为

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);
}
}

就会报错:java.lang.IllegalArgumentException: Structure array elements must use contiguous memory (bad backing address at Structure array index 1)

请问如何解决这个问题?谢谢!
...全文
1292 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zeng_tao1234 2014-01-14
  • 打赏
  • 举报
回复
我现在也在学调用dll,dll里面有个结构体,struct boy{ char *name; char *sex; char *nickName; int age; char birthday; }; int justShow(boy boy[],int len,string retMsg) 还有个方法,在java 中怎么传数据boy[],我用个对象类数组传 报错Unsupported array argument type
harckers 2013-07-17
  • 打赏
  • 举报
回复
public static void main(String[] args) { UserStruct.ByValue user = new UserStruct.ByValue(); UserStruct.ByValue[] userStructs = (UserStruct.ByValue[])user.toArray(CLIENT_INPUT_SIZE); for(int i = 0; i < CLIENT_INPUT_SIZE; i++) { userStructs[i].id = new NativeLong(100); userStructs[i].age = 30; userStructs[i].name = new WString("沈东良"); } TestDll1.INSTANCE.sayUser(userStructs); }
zhinengfangcheng 2012-07-19
  • 打赏
  • 举报
回复
怎么解决的????求答案
zhoulijunzzzz 2011-12-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wangbaosong0 的回复:]
引用 4 楼 qybao 的回复:

C++的调用是连续地址的,即pUserStruct[i].id,是个数组,地址是连续的
而java每次userStructs[i] =new UserStruct();地址是不连续的
感觉好像是这个问题

恩,是这个问题。现在问题解决了哈。谢谢了。
[/Quote]
请问你怎么解决的饿??
turing-complete 2011-06-14
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wangbaosong0 的回复:]
引用 2 楼 mougaidong 的回复:
接口部分应当尽量简单,传输基本数据类型是一个措施。


基本类型,比如 int[] 没有问题,现实是要传结构体,并且还是结构体数组。
[/Quote]

到底是有高手啊,能洞悉这语言中微妙的差别。
wangbaosong0 2011-06-13
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 qybao 的回复:]

C++的调用是连续地址的,即pUserStruct[i].id,是个数组,地址是连续的
而java每次userStructs[i] =new UserStruct();地址是不连续的
感觉好像是这个问题
[/Quote]
恩,是这个问题。现在问题解决了哈。谢谢了。
turing-complete 2011-06-10
  • 打赏
  • 举报
回复
接口部分应当尽量简单,传输基本数据类型是一个措施。
qybao 2011-06-10
  • 打赏
  • 举报
回复
像这种情况,可以考虑改一下接口,java端用字节数组发送,C端用字节数组接收,然后C再通过memcpy的方式,把字节数组内容复制到结构体中还原结构体。
qybao 2011-06-10
  • 打赏
  • 举报
回复
C++的调用是连续地址的,即pUserStruct[i].id,是个数组,地址是连续的
而java每次userStructs[i] =new UserStruct();地址是不连续的
感觉好像是这个问题

wangbaosong0 2011-06-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 mougaidong 的回复:]
接口部分应当尽量简单,传输基本数据类型是一个措施。
[/Quote]

基本类型,比如 int[] 没有问题,现实是要传结构体,并且还是结构体数组。
wangbaosong0 2011-06-09
  • 打赏
  • 举报
回复
传递int型数组,运行结果正常。然而换成这个结构体类就不行了!

50,541

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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