JNI调用delphi写的dll时出错
在做JNI调用delphi的一个参数为结构体的函数(该参数的结构体有三个int型和一个string型数据,该函数的目的是从计算机外接设备上获取数据来填满这个结构体参数)时...
在做JNI调用delphi的一个参数为结构体的函数(该参数的结构体有三个int型和一个string型数据,该函数的目的是从计算机外接设备上获取数据来填满这个结构体参数)时,我采用的这样的方法:在C++中定义一个结构体,然后把结构体赋值给该函数,然后分别用四个函数来返回这个结构体中的四个值到JAVA端,供java程序使用,现在的问题是如果我用一个定时器来定时运行这个带结构体参数的函数,能运行一会并输出正确值然后报
# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x10001b0d, pid=18612, tid=15552
的错误,如果使用窗体加按钮的形式第一次点击输出一些垃圾值,第二次点击报
# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x03602ee1, pid=19408, tid=19084的错误
C++中的代码是这样的
struct TDeviceEvent
{
int USBBoxNo;
int Channel;
int EventType;
string EventString;
};
TDeviceEvent Device;
typedef bool (__stdcall *getdeviceevent)(TDeviceEvent Device1);
JNIEXPORT jboolean JNICALL Java_JNI_GetDeviceEvent(JNIEnv *env, jobject jo)
{
bool result = 1;
HINSTANCE dllhandle;
dllhandle = LoadLibrary("psusbcore.dll");
getdeviceevent GetDeviceEvent = (getdeviceevent)GetProcAddress(dllhandle, "GetDeviceEvent");
result = GetDeviceEvent(Device);
return result;
}JNIEXPORT jint JNICALL Java_JNI_GetEventBox(JNIEnv *env, jobject jo)
{
return Device.USBBoxNo;
}
JNIEXPORT jint JNICALL Java_JNI_GetEventCh(JNIEnv *, jobject)
{
return Device.Channel;
}
JNIEXPORT jint JNICALL Java_JNI_GetEventType(JNIEnv *, jobject)
{
return Device.EventType;
}
JNIEXPORT jstring JNICALL Java_JNI_GetEventString(JNIEnv *, jobject)
{
return Device.EventString;
}
好几天了一直卡在这里,不知道什么原因,我怀疑是结构体格式对齐或者string类型匹配的问题的问题,但不知道应该如何对齐 展开
# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x10001b0d, pid=18612, tid=15552
的错误,如果使用窗体加按钮的形式第一次点击输出一些垃圾值,第二次点击报
# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x03602ee1, pid=19408, tid=19084的错误
C++中的代码是这样的
struct TDeviceEvent
{
int USBBoxNo;
int Channel;
int EventType;
string EventString;
};
TDeviceEvent Device;
typedef bool (__stdcall *getdeviceevent)(TDeviceEvent Device1);
JNIEXPORT jboolean JNICALL Java_JNI_GetDeviceEvent(JNIEnv *env, jobject jo)
{
bool result = 1;
HINSTANCE dllhandle;
dllhandle = LoadLibrary("psusbcore.dll");
getdeviceevent GetDeviceEvent = (getdeviceevent)GetProcAddress(dllhandle, "GetDeviceEvent");
result = GetDeviceEvent(Device);
return result;
}JNIEXPORT jint JNICALL Java_JNI_GetEventBox(JNIEnv *env, jobject jo)
{
return Device.USBBoxNo;
}
JNIEXPORT jint JNICALL Java_JNI_GetEventCh(JNIEnv *, jobject)
{
return Device.Channel;
}
JNIEXPORT jint JNICALL Java_JNI_GetEventType(JNIEnv *, jobject)
{
return Device.EventType;
}
JNIEXPORT jstring JNICALL Java_JNI_GetEventString(JNIEnv *, jobject)
{
return Device.EventString;
}
好几天了一直卡在这里,不知道什么原因,我怀疑是结构体格式对齐或者string类型匹配的问题的问题,但不知道应该如何对齐 展开
展开全部
……别,C++那个结构体中string都出来了。
基本上是不用指望其他语言可以调用了。
C++本身也不一定就能成功调用这个DLL(除非STL库和编译器一致,并使用同一套堆内存管理算法)
基本上是不用指望其他语言可以调用了。
C++本身也不一定就能成功调用这个DLL(除非STL库和编译器一致,并使用同一套堆内存管理算法)
更多追问追答
追问
在C++的结构中我试过用char*还是同样的问题,想请教一下是我的代码的问题还是delphi的string类型的问题,我在网上也查到说是delphi中如果用string的话通用性就很差,只有delphi和cbuilder可以调用但我是VC++6.0,不管是delphi的dll中有widestring类型的参数还是有string类型的结构,都无法正确调用,而其他类型的函数就能正确调用,dll可修改
追答
不对,仔细看了你的代码,EventString不是string吗为什么作为jstring可以正确返回(编译没报错?
你C++直接调用delphi的代码,没问题是吗?
如果是,那么问题可能出在java那边。
对于字符串传递,因为字符串并不是一个寄存器或者固定4个字节这样子的变量,
所以它涉及到一个这样的问题,存放字符串的内存在哪里,存放字符串的内存由谁来申请、由谁来释放,用的是哪一套内存管理程序,这样……比较麻烦
我没用过jni,因为根本不会java。不过就我使用C#的经验来说,如果java有这样一种机制,可以在byte数组和string之间转换,那么由C++来返回一个byte数组是最保险的:结构体中的string完全由C++进行内存管理,java的string完全由java进行内存管理,之间数据交换的时候,由java申请一个byte数组,作为参数传入,然后由C++将string复制到这个数组中,这样就很简单地解决了字符串的内存所属问题,……
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询