关于一个JNI 参数传递的问题

iefoahz3802 2008-03-16 05:42:27
我有个问题 请问下各位
我现在有个vb的 .dll文件 ,里面函数为
closecomm(comm_value& )
参数为 comm_value 的结构为

Public Type Comm_value
com_port As String * 3 //传入参数
dis_value As String * 40 //传出参数
data_len As String * 2 //传出参数
End Type

现在我使用jni的方法 重新用c++写个dll让java 调用

代码如下
main.h

class comm_value{
public:
char com_port[10];
char dis_value[40];
char data_len[2];

};

typedef int __stdcall (*SendCard_c_mcom_set)(comm_value& value);
typedef int __stdcall (*SendCard_closecomm)(comm_value& value);


main.cpp

JNIEXPORT jint JNICALL Java_SendCardJava_c_1mcom_1set
(JNIEnv * env, jobject, jobject comm)
{
jclass commValueCls = env->FindClass("Comm_Value");
jfieldID fid_CommValue_comport = env->GetFieldID(commValueCls,"com_port","Ljava/lang/String;");
jobject proCommport = env->GetObjectField(comm,fid_CommValue_comport);
jstring ppCommPort = (jstring)env->GetObjectField(proCommport,fid_CommValue_comport);

HINSTANCE DLLHandle;
SendCard_c_mcom_set sc_c_mcom_set;
int open_result = 0;

DLLHandle = LoadLibrary("D:\\DGD4V3.0\\sendcard.dll"); //

if (DLLHandle) //call crmp timeout hook
{
try
{
sc_c_mcom_set = (SendCard_c_mcom_set)GetProcAddress(DLLHandle,"c_mcom_set");
if (sc_c_mcom_set)
{
-----------------------------------------
问题: 下面的我调用vb 的dll 中的函数 c_mcom_set (Comm_value & parameter ) parameter 参数应该如何转换成Comm_value 类
并使引用中的传出的2个参数怎样传出 希望大家能帮帮忙 谢谢~
open_result = sc_c_mcom_set(commValueCls);

}
}catch(...)
{
}
}
}
...全文
726 39 打赏 收藏 转发到动态 举报
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
txzsp 2011-11-11
  • 打赏
  • 举报
回复
给LZ推荐一个JNI的使用,有源码和大量注释,LZ一定要试下:
http://download.csdn.net/detail/txzsp/2285294
iihero 2008-03-21
  • 打赏
  • 举报
回复
小兄弟,建议你一步步简化问题,
比如,我给你出一道题,你什么时候会做了,上述乱码问题就都解决了。

class TestJava
{
private native printHello(String hello);
public static String getStrCallback(String str);
};

要求,在实现printHello方法的C代码里头,要进行TestJava class的getStrCallback方法回调,并且,打印的是中文串。
比如“中文测试”。

这里边就包含了unicode16BE到gbk编码相互之间的转换。
iefoahz3802 2008-03-21
  • 打赏
  • 举报
回复
最后结贴,比较遗憾的是 我一直没搞清楚 为什么我传对象进来string属性取出来 的是乱码 ,直接传string没有问题.
iefoahz3802 2008-03-20
  • 打赏
  • 举报
回复
首先我是
JNIEXPORT jstring JNICALL Java_com_autotoll_hk_cms_integrated_reader_SendCardJava_getCardNo
(JNIEnv *env, jobject, jobject comm, jobject keyset, jobject zone)
{
jclass commValueCls = env->FindClass("com/autotoll/hk/cms/integrated/module/Comm_value");
//或着
//jclass commValueCls = env->GetObjectClass("comm");
jfieldID fid_CommValue_comport = env->GetFieldID(commValueCls,"com_port","Ljava/lang/String;");
jstring ppCommPort = (jstring)env->GetObjectField(commValueCls,fid_CommValue_comport);
这样得到jstring 之后用上面的转换的, 显示的总是乱码 请各位帮忙
iefoahz3802 2008-03-20
  • 打赏
  • 举报
回复
为什么我试了下面2个函数都 jstring 转换成char* 都是乱码 ,请高手帮看看
char* jstringTostring(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("utf-8");
jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
jsize alen = env->GetArrayLength(barr);
jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
env->ReleaseByteArrayElements(barr, ba, 0);
return rtn;
}

int JStringToChar(JNIEnv * env, jstring str)
{
int nLen = env-> GetStringLength(str) * 2 + 1;
char *pcName = new char[nLen];
memset(pcName, 0, nLen);

const wchar_t * w_buffer = (wchar_t*) env->GetStringChars(str, 0);
nLen = WideCharToMultiByte(CP_ACP, 0, w_buffer, wcslen(w_buffer) + 1, pcName, nLen, NULL, NULL);
printf("%s\n",pcName);
env->ReleaseStringChars(str, (unsigned short*)w_buffer);

return strlen(pcName);
}
sunhw2002 2008-03-20
  • 打赏
  • 举报
回复
mark
iefoahz3802 2008-03-19
  • 打赏
  • 举报
回复
现在还有个小问题 问下大家,
jni 在javac javah 时应该在什么目录下? 再就是dll应该放什么路径下?
我在javah 包含包名后,dll也改了名字 调用时还报 java.lang.UnsatisfiedLinkError: getCardNo(方法名错误)
iefoahz3802 2008-03-19
  • 打赏
  • 举报
回复
JNIEXPORT jstring JNICALL Java_SendCardJava_getCardNo
(JNIEnv *env, jobject, jobject comm, jobject keyset, jobject zone)
{
jclass commValueCls = env->FindClass("module/Comm_value");
jfieldID fid_CommValue_comport = env->GetFieldID (commValueCls,"com_port","Ljava/lang/String;");
jstring ppCommPort = (jstring)env->GetObjectField(commValueCls,fid_CommValue_comport);

我只是想得到comm 对象的com_port 我在java 赋的是"1" 这样取出来的 是些乱码 ,请帮忙看看.
hoszone 2008-03-19
  • 打赏
  • 举报
回复
通过数组就可以吧???/
iefoahz3802 2008-03-19
  • 打赏
  • 举报
回复
现在调用的问题基本解决,现在还存在2个问题,希望大家帮下忙.
第一个:
我用vb 调用dll的方法 传进去的这样的类型进去的
Public Type comm_value
com_port As String * 1
dis_value As String * MAXCARDALL
data_len As String * 2
End Type

Dim MyCOM As comm_value
c_mread_card(MyCOM, MyKeySet, MyZone)

传出来的MyCOM.dis_value 是正确的, F1FBC8FFC8FF000000000000000000005510

但在c++里面我定义的
class comm_value{
public:
char com_port[10];
char dis_value[100];
char data_len[2];

};

comm_value MyCOM ;
Result = sc_c_mread_card(MyCOM, MyKeySet, MyZone);
但是传出来的MyCom.disvalue 只有 8FF000000000000000000005510

第二个问题:
是怎么把java 传进来的String 类型转换成char*,再 怎么把c++的char* 转换成String

多谢各位的帮忙!
SongRN 2008-03-18
  • 打赏
  • 举报
回复
unsigned short* 和wchar_t*不是一回事吗?
typedef unsigned short wchar_t; //这事它的宏定义.
iefoahz3802 2008-03-18
  • 打赏
  • 举报
回复
const wchar_t* w_buffer = env-> GetStringChars( sSrcName, 0 );
这个函数得到是unsigned short* 请问怎么转换成wchar_t*的?
SongRN 2008-03-18
  • 打赏
  • 举报
回复
加头文件
#include <string.h>
#include <stdio.h>
#include <windows.h>
healer_kx 2008-03-18
  • 打赏
  • 举报
回复
2楼的,这里面出现了一个叫龍子龍孫的,他出现的地方,其他人只能当菜鸟了。

菜草飘过。。。
healer_kx 2008-03-18
  • 打赏
  • 举报
回复
告诉我编译错误,这个问题很简单。
iefoahz3802 2008-03-18
  • 打赏
  • 举报
回复
怎么我用const wchar_t* w_buffer = env-> GetStringChars( sSrcName, 0 );
nLen = WideCharToMultiByte(CP_ACP, 0,
w_buffer, wcslen(w_buffer) + 1, pcName, nLen, NULL, NULL);
转换程序报错呢?
SongRN 2008-03-18
  • 打赏
  • 举报
回复
哈哈哈,小子你碰上我,算你命好,给你看段代码.
jstring 装的是UNICODE的字符,你要把它转成ASCII

JNIEXPORT jint JNICALL Java_DllConvert_TScan_selectSource
(JNIEnv *env, jobject, jstring sSrcName)
{
int nLen = env->GetStringLength(sSrcName) * 2 + 1;
char *pcName = new char[nLen];
memset( pcName, 0, nLen );

const wchar_t* w_buffer = env->GetStringChars( sSrcName, 0 );
nLen = WideCharToMultiByte(CP_ACP, 0,
w_buffer, wcslen(w_buffer) + 1, pcName, nLen, NULL, NULL);

//上面几行就是把jstring 类型转为char*

int nRes = TSCAN_SelectSource(pcName); //这是我的函数.

env->ReleaseStringChars(sSrcName, w_buffer); //用完了要释放,但不释放好象也行,似乎没有内存泄露,呵呵不清楚.
delete pcName;
return nRes;
}
iefoahz3802 2008-03-17
  • 打赏
  • 举报
回复
没明白,能帮写明白点吗?
iihero 2008-03-17
  • 打赏
  • 举报
回复
comportStr为空,是导致后边出错的根本原因。
你看看const jchar * GetStringChars(JNIEnv *env, jstring string,
jboolean *isCopy);

返回的是jchar*, 它是unicode char*啊。相当于是short*
你得把它们转换成gbk串才行。
iefoahz3802 2008-03-17
  • 打赏
  • 举报
回复
const char* comportStr =(char*) env->GetStringChars(ppCommPort,0);
printf("%s\n",comportStr);
是个空的,请问我的代码 哪写的不对?
加载更多回复(19)

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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