我有个问题 请问下各位
我现在有个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.hclass 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.cppJNIEXPORT 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(...)
{
}
}
}
我现在有个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.hclass 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.cppJNIEXPORT 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(...)
{
}
}
}
native myMethod() 之类的总之,书写一个类或者一个方法为native ,
帮up
我现在有个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_closecomm
(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);
char * comportStr =(char*)env-> GetStringUTFChars(ppCommPort,NULL); jfieldID fid_CommValue_disvalue = env-> GetFieldID(commValueCls,"dis_value","Ljava/lang/String;");
jobject proDisvalue = env-> GetObjectField(comm,fid_CommValue_disvalue);
jfieldID fid_CommValue_DataLen = env-> GetFieldID(commValueCls,"data_len","Ljava/lang/String;");
jobject proDataLen = env-> GetObjectField(comm,fid_CommValue_DataLen); HINSTANCE DLLHandle;
SendCard_closecomm sc_closecomm;
int close_result = 0; DLLHandle = LoadLibrary("D:\\DGD4V3.0\\sendcard.dll"); // if (DLLHandle) //call crmp timeout hook
{
try
{
comm_value value ;
strcpy(value.com_port,comportStr) ; sc_closecomm = (SendCard_c_mcom_set)GetProcAddress(DLLHandle,"closecomm");
if (sc_closecomm)
{
close_result = sc_closecomm(value); // env-> SetObjectField(proDisvalue,fid_CommValue_disvalue,env-> NewStringUTF(value.dis_value)) ;
// env-> SetObjectField(proDataLen,fid_CommValue_DataLen,env-> NewStringUTF(value.data_len )) ;
}
}catch(...)
{
}
}
return close_result;
}
java 代码
public class SendCardJava {
public native int closecomm(Comm_value Comm_value); static
{
System.loadLibrary("JavaSendCard");
}
} 调用 public class SendCardJavaDLLApp { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
SendCardJava sendCardJava = new SendCardJava(); Comm_value comm = new Comm_value();
comm.com_port = "COM1"; System.out .println("Close Result : " + sendCardJava.closecomm(comm));
System.out.println("Data Len: " + comm.data_len );
System.out .println("Dis Value: " + comm.dis_value ); }
现在报错误
#
# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d890e20, pid=4312, tid=6096
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0-b105 mixed mode, sharing)
# Problematic frame:
# V [jvm.dll+0xd0e20] 希望各位能帮忙解决下 谢谢
如果是的话,可以用JAVA的标准API,comm.jar,它提供了跨平台的对COM端口的读写以及打开关闭等操作
public class Comm_value {
public String com_port; public String dis_value; public String data_len;
}请高手们多给点意见
在java代码中增加print语句,进行诊断。
这个调用应该不麻烦。
JNIEXPORT jint JNICALL Java_SendCardJava_closecomm
(JNIEnv *env, jobject, jobject comm)
// get class Comm_value refrence
jclass commValueCls = env->GetObjectClass(comm); //get Comm_value jfiledID comport
jfieldID fid_CommValue_comport = env->GetFieldID(commValueCls,"com_port","Ljava/lang/String;"); //get string comm_port
jstring ppCommPort = (jstring)env->GetObjectField(commValueCls,fid_CommValue_comport); //transfer string to char*
const char* comportStr =(char*) env->GetStringChars(ppCommPort,0); 请问下下是不是这样转换的,我为什么这样调用后,程序就报错误呢
DLLHandle = LoadLibrary("D:\\DGD4V3.0\\sendcard.dll"); // if (DLLHandle) //call crmp timeout hook
{
try
{
comm_value value ;
如果是strcpy(value.com_port,"COM1") ; 就调用正确
如果是strcpy(value.com_port,comportStr) ; 调用的时候就报错,我不知道comportStr 有没问题 sc_closecomm = (SendCard_c_mcom_set)GetProcAddress(DLLHandle,"closecomm");
if (sc_closecomm)
{
close_result = sc_closecomm(value); // env-> SetObjectField(proDisvalue,fid_CommValue_disvalue,env-> NewStringUTF(value.dis_value)) ;
// env-> SetObjectField(proDataLen,fid_CommValue_DataLen,env-> NewStringUTF(value.data_len )) ;
}
}catch(...)
{
}
}
const char* comportStr =(char*) env-> GetStringChars(ppCommPort,0); ........ print出来试试。
printf("%s\n",comportStr);
是个空的,请问我的代码 哪写的不对?
你看看const jchar * GetStringChars(JNIEnv *env, jstring string,
jboolean *isCopy); 返回的是jchar*, 它是unicode char*啊。相当于是short*
你得把它们转换成gbk串才行。
int len = env->GetStringUTFLength(ppCommPort); char* comportStr = env->GetStringUTFChars(name, iscopy)
看它里边有没有内容,这个是utf-8编码的,如果是ansi char,不会有什么问题。如果是中文,则要转到gbk,才能显示。
还好,你的类最好是用包组织一下.试试看
LEN
96comportStr
浼�悼毽�秵甓版秵缃�稁绱愭秵砘版秵殳版秵顐愭秵顐�秵绉愭秵旌�秵霋版秵鞝版秵顐犳秵顑�秵飹�秵伀浿?涆?涆罀涎紐涆?涆?涆涆涆秐涆?涆?涆?涆涆涆?涆得到这些乱码
奇怪了我在java调用的时候
Comm_value comm = new Comm_value();
comm.com_port = "COM1";
System.out .println("Close Result : " + sendCardJava.closecomm(comm));都是ansi char 为什么会这样呢
http://blog.sina.com.cn/s/blog_4ec996be01008lz9.html总共2个方法,一个通过JNI,一个通过JNative,因为是笔记,没写得明白,只有代码,希望对你有所启发,建议善用GOOGLE。
//get string comm_port
jstring ppCommPort = (jstring)env-> GetObjectField(commValueCls,fid_CommValue_comport); //transfer string to char*
const char* comportStr =(char*) env-> GetStringChars(ppCommPort,0); printf("%s\n",comportStr); 我在java调用传入的是"1" 打印出来的是乱码
jstring 装的是UNICODE的字符,你要把它转成ASCIIJNIEXPORT 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;
}
nLen = WideCharToMultiByte(CP_ACP, 0,
w_buffer, wcslen(w_buffer) + 1, pcName, nLen, NULL, NULL);
转换程序报错呢?
#include <string.h>
#include <stdio.h>
#include <windows.h>
这个函数得到是unsigned short* 请问怎么转换成wchar_t*的?
typedef unsigned short wchar_t; //这事它的宏定义.
第一个:
我用vb 调用dll的方法 传进去的这样的类型进去的
Public Type comm_value
com_port As String * 1
dis_value As String * MAXCARDALL
data_len As String * 2
End TypeDim 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 多谢各位的帮忙!
(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" 这样取出来的 是些乱码 ,请帮忙看看.
jni 在javac javah 时应该在什么目录下? 再就是dll应该放什么路径下?
我在javah 包含包名后,dll也改了名字 调用时还报 java.lang.UnsatisfiedLinkError: getCardNo(方法名错误)
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);
}
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 之后用上面的转换的, 显示的总是乱码 请各位帮忙
比如,我给你出一道题,你什么时候会做了,上述乱码问题就都解决了。class TestJava
{
private native printHello(String hello);
public static String getStrCallback(String str);
};要求,在实现printHello方法的C代码里头,要进行TestJava class的getStrCallback方法回调,并且,打印的是中文串。
比如“中文测试”。这里边就包含了unicode16BE到gbk编码相互之间的转换。
http://download.csdn.net/detail/txzsp/2285294