
构造对象:
public struct ToJsonMy
{
public string result { get; set; } //属性的名字,必须与json格式字符串中的"key"值一样。
public string res_info { get; set; }
public string queryorder_info { get; set; } }
转换过程:
public static void JsonMy()
{
string json = Jsonstr("D:\\json\\jsonmy1txt");//Jsonstr函数读取json数据的文本txt
JavaScriptSerializer js = new JavaScriptSerializer(); //实例化一个能够序列化数据的类
ToJsonMy list = jsDeserialize<ToJsonMy>(json); //将json数据转化为对象类型并赋值给list
string result = listresult;
string res_info = listres_info;
string queryorder_info = listres_info;
}
json包含对象数组 json数据:jsonmy4txt
{"result":"0","res_info":"ok","queryorder_info":{"order_num":"5","orderdetail":[{"CFTUin":"769839263","CancelDeadline":"2013-09-12 23:00:00","CheckInDate":"2013-09-12 00:00:00","CheckOutDate":"2013-09-13 00:00:00","CityID":"0101","CurrencyCode":"RMB","HotelID":"00301105","HotelName":"乐家连锁(北京天坛南门店)(原速8酒店(北京天坛南店)",
"ListID":"1000000005201308280002999652","PayAmt":"228","PayType":"0","RommsCnt":"1","SPTransID":"65202157","State":"4"},{"CFTUin":"248486133","CancelDeadline":"2013-10-13 23:00:00","CheckInDate":"2013-10-13 00:00:00","CheckOutDate":"2013-10-18 00:00:00","CityID":"0201","CurrencyCode":"RMB","HotelID":"10201314","HotelName"
"ListID":"1000000005201308280002999413","PayAmt":"1140","PayType":"0","RommsCnt":"1","SPTransID":"65197226","State":"4"}]}}
具体执行步骤为:
make
cd bin
/runsh
下面来介绍一下在这个项目中所实现的实例:
如何调用标准C/c++中的函数--例如:printf()
2 如何调用C/c++中自定义的函数
3 如何在jni函数中访问java类中的对象实例域
4 如何在jni函数中访问java类中的静态实例域
5 如何在jni函数中调用java对象的方法
6 如何在jni函数中调用java类的静态方法
7 如何在jni函数中传递基本数据类型参数
8 如何在jni函数中传递对象类型参数
9 如何在jni函数中处理字符串
10 如何在jni函数中处理数组
11 处理jni函数中的返回值情况
12 在jni中实现创建java类对象
二、基本步骤:
在介绍这些例子之前,让我们先来看看编写jni方法所需要的基本步骤,这些实例都是用c来实例来讲解,至于c++的实例和c的实例区别不大,只要作稍微的修改即可,在文档的末尾我们将介绍这些内容:
1、要想定义jni方法,首先得要在java语言中对这一方法进行声明(自然这一声明过程要在类中进行)
声明格式如下:
publicnativevoid print(); SystemloadLibrary(“JNIExamples”); }
jni 函数用关键字native方法声明。
2、对该类的源文件进行编译使用javac命令,生成相应的class文件。
3、用javah -jni为函数生成一个在java调用和实际的c函数之间的转换存根,该存根通过从虚拟机栈中取出参数信息,并将其传递给已编译的C函数来实现转换。
4、建立一个特殊的共享库,并从该共享库到处这个存根,在上面的例子中使用了SystemloadLibrary,来加载libJNIExamples共享库。
三、配置运行环境:
在编写一个简单的jni函数之前我们必须配置相应的运行环境。jdk的配置在这里就不作介绍,这里主要说的是库的路径。当调用SystemloadLibrary()时,编译器会到我们系统设置的库路径中寻找该库。修改路径的方法和修改任何环境变量的方法基本相同,只要在/etc/bashbashrc目录下增加一行LD_LIBRARY_PATH=:/lib:$(LD_LIBRARY_PATH)即可。也可以通过命令行export
LD_LIBRARY_PATH=:/lib:$(LD_LIBRARY_PATH)
四、运行实例分析:
1、实例一:在jni中调用标准c中自带的函数printf():
下面以实例1为例来详细说明编写jni方法的详细过程。
(1)、定义包含jni函数的类Printjava:
{
/
the print() function will call the printf() funcion which is a ANSI c
funciton
/publicnativevoid
print();
SystemloadLibrary("JNIExamples"); } }
在上面的实例中,使用public native void
print();语句来定义了一个Print类的jni方法。并用SysgemloadLibrary(“JNIExamples”)语句来加载libJNIExamplesso库。注意:加载的语句一定要用static关键字声明在静态块中,以保证引用该类时该库始终被加载。
(2)、对该类进行编译:javac Printjava。生成Printclass类,然后用javah 产生一个Printh的头文件:javah Print。长生的Printh文件格式如下:
/ DO NOT EDIT THIS FILE - it is machine generated // Header for class
Print / JNIEXPORT void JNICALL Java_Print_print (JNIEnv ,
jobject); }
其中的加粗字体为要实现的JNI函数生命部分。
(3)、编写JNI函数的实现部分Printc
JNIEXPORT void JNICALL Java_Print_print (JNIEnv env, jobject obj) {
printf("example1:in this example a printf() function in ANSI C is
called\n"); printf("Hello,the output is generated by printf()
function in ANSI C\n"); }
在这个文件中实现了一个简单的Jni方法。该方法调用ANSI C 中的printf()函数,输出了两个句子。
(4)、将本地函数编译到libJNIExamplesso的库中:
使用语句:gcc -fPIC -I/usr/jdk15/include -I/usr/jdk15/include/linux -shared -o libJNIExamplesso Printc。
(5)、至此Jni函数已全部实现,可以在java代码中调用拉。
在此我们使用一个简单的类来对实现的jni方法进行测试,下面是PrintTestjava的源代码部分:
publicstaticvoid main(String[] args) { Print p = new Print(); pprint(); } }
(6)、对PrintTestjava进行编译执行得到如下结果:
example1:in this example a printf() function in ANSI C is called
Hello,the output is generated by printf() function in ANSI C
下面介绍的每个实例实现的步骤也都是按着上述步骤执行的。所以介绍时只介绍实现的关键部分。
2、实例二、调用c 语言用户定义的函数(源程序为:java/Cfunctionjava java/C_functionTestjava src/Cfunctionc src/Cfunctionh )
当需要在java程序中调用用c所实现的函数是,需要在需要调用该c函数的类中定义一个jni方法,在该jni方法中去调用该c函数,相当于用java方法把c函数封装起来,以供java程序调用。
在实例二中我们简单定义了一个printHello()函数,该函数的功能只是输出一句话,如果要在java程序中调用该函数,只需在jni函数中调用即可,和调用ANSI C中自带的prinf()函数没有任何区别。
3、实例三、在jni函数中访问java类中的对象实例域(源程序为:java/CommonFieldjava java/CommonFieldTestjava src/CommonFieldc src/CommonFieldh )
jni函数的实现部分是在c 语言中实现的,如果它想访问java中定义的类对象的实例域需要作三步工作,
(1)调用GetObjectClass()函数得到该对像的类,该函数返回一个jclass类型值。
(2)调用GetFieldID()函数得到要访问的实例域在该类中的id。
(3)调用GetXXXField()来得到要访问的实例域的值。其中XXX和要访问的实例域的类型相对应。
在jni中java 编程语言和c 语言数据类型的对应关系为java原始数据类型前加 'j' 表示对应c语言的数据类型例如boolean 为jboolean ,int 为 jint,double 为jdouble等。对象类型的对应类型为jobject。
在本实例中,您可以看到我们在java/CommonFieldjava 中定义了类CommonField类,其中包含int a , int b
两个实例域,我们要在jni函数getCommonField()中对这两个域进行访问和修改。你可以在
src/CommonFieldc中找到该函数的实现部分。
以下语句是对该域的访问(以下代码摘自:src/CommonFieldc):
jclass class_Field = (env)->GetObjectClass(env,obj); jfieldID fdA =
(env)->GetFieldID(env,class_Field,"a","I"); jfieldID fdB =
(env)->GetFieldID(env,class_Field,"b","I"); jint valueA =
(env)->GetIntField(env,obj,fdA); jint valueB =
(env)->GetIntField(env,obj,fdB);
在jni中对所有jni函数的调用都要用到env指针,该指针也是每一个本地方法的第一个参数,他是函数指针表的指针,所以,必须在每一个jni调用前面加上(env)->GetObjectClass(env,obj)函数调用返回obj对像的类型,其中obj
参数表示要你想要得到类型的类对象。
jfieldID GetFieldID(JNIEnv env,jclass cl, const char name[], const char
sig[]) 该函数返回一个域的标识符name 表示域名,sig表示编码的域签名。所谓编码的签名即编码类型的签名在上例中类中的a实例域为int
型,用"I”来表示,同理"B” 表示byte ,"C” 表示 char , “D”表示 double ,”F”
表示float,“J”表示long, “S” 表示short , “V” 表示void ,”Z”表示 boolean类型。
GetIntField(env,obj,fdA),用来访问obj对象的fdA域,如果要访问的域为double类型,则要使用GetDoubleField(env,obj,fdA)来访问,即类型对应GetXXXField中的XXX。
以下函数用来修改域的值:
(env)->SetIntField(env,obj,fdA,109); (env)->SetIntField(env,obj,fdB,145);
这和获得域的值类似,只是该函数多了一个要设置给该域的值参数。
访问对象实例域的相关函数如下:
jfieldID GetFieldID(JNIEnv env, jclass cl, const char name[], const char sig[])
该函数返回一个域的标识符。各参数含义如下:
env JNI 接口指针;cl 类对象 ; name 域名; sig 编码的域签名
XXX GetXXXField(JNIEnv env, jobject obj, jfieldID id)
该函数返回域的值。域类型XXX是Object, Boolean, byte, char , short, int ,long ,float, double 中类型之一。
参数 env JNI借口指针;obj为域所在对象;id为域的标识符。
void SetXXXField(JNIEnv env,jobject obj, jfieldID id, XXX value)
该函数用于设置域的值。XXX的含义同上,
参数中env, obj , id 的含义也同上,value 值为将要设置的值。
4、实例四:在jni函数中访问类的静态实例域 (java/Fieldjava java/FieldTestjava src/Fieldc src/Fieldh)
因为静态实例域并不属于某个对象,而是属于一个类,所以在要访问静态实例域时,和访问对象的实例域不同,它所调用的函数是(以实例四来说明,一下代码摘自src/Fieldc):
jclass class_Field = (env)->FindClass(env,"Field"); jfieldID fdA =
(env)->GetStaticFieldID(env,class_Field,"a","I"); jint valueA =
(env)->GetStaticIntField(env,class_Field,fdA);
(env)->SetStaticIntField(env,class_Field,fdA,111);
由于没有对象,必须使用FindClass代替GetObjectClass来获得类引用。在FindClass()的第二个参数是类的编码签名,类的编码签名和基本类型的编码签名有所不同,如果类在当前包中,就直接是类的名称,如果类不在当前包中则要加入该类的详细路径:例如String类在javalang包中,则String的签名要写成(
Ljava/lang/String;),其中的(L和;)是不可少的,其中(;)是表达是的终止符。其他三个函数和访问对象数据域基本没什么区别。
5、实例五:在jni函数中调用java对象的方法(java/CommonMethodjava java/CommonMethodTestjava src/CommonMehodc src/CommonMethodh )
在jni函数中我们不仅要对java对象的数据域进行访问,而且有时也需要调用java中类对象已经实现的方法,实例五就是关于这方面的实现的。在src/CommonMethodc中我们可以找到下面的代码:
JNIEXPORT void JNICALL Java_CommonMethod_callMethod (JNIEnv env,
jobject obj, jint a, jstring s) { printf("example 5:in this
example,a object's method will be called\n"); jclass
class_CommonMethod = (env)->GetObjectClass(env,obj); jmethodID
md =
(env)->GetMethodID(env,class_CommonMethod,"print","(ILjava/lang/String;)V");
(env)->CallVoidMethod(env,obj,md,a,s); }
该代码部分展示了如何实现对java类对象函数的调用过程。从以上代码部分我们可以看到,要实现该调用需要有三个步骤,调用三个函数
jclass class_CommonMethod = (env)->GetObjectClass(env,obj);
jmethodID md =
(env)->GetMethodID(env,class_CommonMethod,"print","(ILjava/lang/String;)V");
(env)->CallVoidMethod(env,obj,md,a,s);
GetObjectClass()函数获得要调用对象的类;GetMethodID()获得要调用的方法相对于该类的ID号;CallXXXMethod()调用该方法。
在编写该调用过程的时候,需要注意的仍然是GetMethodID()函数中编码签名的问题,在该实例中,我们要做的是找到CommonMethod类的print(int
a, String s)方法,该方法打印整数a,和字符串s
的直。在函数的编码签名部分(该部分以加粗、并加有下划线)GetMethodID(env,class_CommonMethod,"print","(ILjava/lang/String;)V");
从左往右可以查看,括号中的内容为要调用方法的参数部分内容,I表示第一个参数为int类型,“Ljava/lang/String;”表示第二个参数为String类型,V表示返回值类型为空void,如果返回值类型不为空,则使用相应的类型签名。返回值类型是和下面将要使用的调用该方法的函数CallXXXMethod()相关联的,该函数的xxx要用相应的类型来替换,在此实例中为void,如果返回值类型为int类型则调用该方法的函数就为CallIntMethod()。
6、实例六:在jni函数中调用java类的静态方法(java/Methodjava java/MethodTestjava src/Methodh src/Methodc)
实例五中介绍了如何调用类对象的方法,在此实例中我们将介绍如何调用java类的静态方法在此实例中我们在/java/Methodjava中定义了静态方法:
public static void print() {
Systemoutprintln("this is a static method of class Method");
}
该函数的功能就是打印字符串“ this is a static method of class Method”;
我们在src/Methodc中实现了对该方法调用的jni函数:
JNIEXPORT void JNICALL Java_Method_callMethod (JNIEnv env, jobject
obj) { printf("example 6:in this example, the class's static
method will be called\n"); jclass class_Method =
(env)->FindClass(env,"Method"); jmethodID md =
(env)->GetStaticMethodID(env,class_Method,"print","()V");
(env)->CallStaticVoidMethod(env,class_Method,md); }
和实例五不同的是,我们要调用的三个函数变为:
FindClass()、GetStaticMethodID()、CallStaticVoidMethod()。
其中的机制和实例五是一样的。再次就不做过多的介绍。
7、实例七:jni函数中传递基本数据类型参数(java/Basicjava java/BasicTestjava src/Basicc
src/Basich) 在java/Basicjava中,我们定义了一个public native void raiseValue(int
a)函数,该函数将打印使value的值增加a,并打印原来的value和新的value值。
在src/Basicc中给出了该jni函数的实现部分。
JNIEXPORT void JNICALL Java_Basic_raiseValue (JNIEnv env, jobject
obj, jint a) { printf("example 7: in this example, a integer type
parament will be passed to the jni method\n"); jclass class_Basic =
(env)->GetObjectClass(env,obj); jfieldID
fd = (env)->GetFieldID(env,class_Basic,"value","I"); jint v =
(env)->GetIntField(env,obj,fd); v = v+a;
(env)->SetIntField(env,obj,fd,v); }
在此函数实现中,因为要访问Basic类中的value域,所以调用了GetObjectClass(), GetFieldID(),
GetIntField()函数获取value值,下面一步的 “ = v+a;
”说明,传递基本类型参数的处理方式和在c语言中的基本数据类型的处理无异。
关键是二维对象数组,是不是先把二维的转成一维的for(i=0;i<15;i++){
jobjectArray
newArray=((env)->GetObjectArrayElement(env,
array_clsA,
i));
for(j=0;j<15;j++)
{
jobject
ok_Element=((env)->GetObjectArrayElement(env,
newArray,
j));
}}
var jsonVal = '{"id","111","name":"小杜"}';
这样就构造了一个包含json格式的js变量,后续如果解析;需要转化为json对象
比如:var jObject=jQueryparseJSON(jsonVal );
alert("id="+jObjectid);
public Class JsonObject :JObject
{
public override Parse(string str){
//重写的方法体
}
}
对比
准备数据
实体类:
定义:
使用DataContractJsonSerializer
帮助类:
用法:
输出:
使用JavaScriptSerializer
// using SystemWebScriptSerialization;
var jser = new JavaScriptSerializer();
var json = jserSerialize(new List<Person>() { p1, p2 });
var persons = jserDeserialize<List<Person>>(json);
使用Silverlight
使用JSONNET
输出:
LINQ:
其他:
输出:
c# jobject dictionary性能create table tb_name(id int primary key identity,key int,name varchar)。
需要在项目==》引用==》右键添加引用(R),找到NewtonsoftJsondll。添加引用后,鼠标点击JObject后再右键==》解析即可。
数据类型:
基本数据类型:C#拥有比C/C++或者Java更广泛的数据类型这些类型是bool、byte、sbyte、short、ushort、int、uint、long、ulong、float、double和decimal,像Java一样,所有这些类型都有一个固定的大小又像C和C++一样。
两个基本类:一个名叫object的类是所有其他类的基类。而一个名叫string的类也象object一样是这个语言的一部分作为语言的一部分存在意味着编译器有可能使用它,无论何时在程序中写入一句带引号的字符串,编译器会创建一个string对象来保存它。
1建议用JsonNET
有nuget包的话,直接搜索JsonNET下载;
没有的话,需要上网找一下 NewtonsoftJson 的dll;
地址:>
以上就是关于C#字符串转成JSON对象,并解析出里面的数据全部的内容,包括:C#字符串转成JSON对象,并解析出里面的数据、callstaticvoidmethod函数怎么用、JNI 中如何Get对象数组内各元素的属性值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)