使用JNI和Reflect实现Object向void*的自动转换之二:构想 [原]

来源:互联网 发布:两院院士 知乎 编辑:程序博客网 时间:2024/06/07 12:33

二、构想:发挥各自的语言机制来消除JavaC的指针鸿沟

就是因为存在着这种差异,两种语言的“指针使用上的差异,造成了使用JAVA进行Windows系统编程有一定的困难。我们发现,由于java语言本身的灵活高效,如果使用java包装了windows的有关API后,做Windows系统编程要比C/C++更有开发效率,更加的灵活,所以,使用javaWindows系统编程应该得到鼓励。

为了使得这个过程更为简洁,让程序员集中精力专注于上层逻辑,我们可以考虑自动包装Object成为相应的C语言下的结构体指针。比如上面提到的Rect类,我们期望对它自动包装,在C++语言中使用的形式如下:

JObjectPtr ptr(jrc)            //一个C++对象持有java的对象,此对象负责构造对应的java对象的C结构体,并管理和解释此存储区

RECT* lpRect =  (RECT*)ptr.getBuffer();  //得到C结构体指针,为了安全,转换的类型应该有协议保证

 

//象通常的C语言一样,使用结构体指针

lpRect->top = 100;

……

if(ptr.isChanged())         //判断数据是否改变

       ptr.updateObject(); //更新java对象

 

 

 

 

 

 

 

 

 

 

 

 


我们可以把这个“期望”的代码和前面的通常代码来比较,就可以发现这里已经相当的简洁了。而且应该注意到,这个包装是非侵入式的,对所要包装的对象表面上没有干预,不依赖于对象的类型。我们所希望的是一个“持有”的概念,就是说这个C++对象包装了jobject类型,让它更加的符合C++语言的一套运行规则。

提出了这个功能需求,我们就要考虑它的可行性。想的到,就做的到。考虑到Java语言的灵活机制,特别是强大的Reflect反射机制,我们相信这个功能可以实现,而且可以使用语言本身的机制来解决这个问题。

 

大致的回想一下,javaReflect机制,主要是运行时得到对象本身的元信息,比如说对象的类型,对象的域(数据成员)信息和对象的方法信息。这个强大的机制,可以让我们在运行时查询、构造和操作指定类型的对象,而此对象并不是代码明白的写出来的。对应的主要包是java.lang.reflect,关键的类是Class,Field,Modifier等。

C/C++中没有这样的功能,因为类编译后就成了一段数据区,数据区中没有int之类的类型标定,更没有类成员名称。类的方法被编译器加上了一个this参数,成了一个个独立的函数,而函数本质上只是地址值而已。

然而,C/C++有着简单和直接的逻辑,就是可以使用指针来操作数据。如果我们明晰某段数据的明确特征,就可以“手动”构造一个相应的结构体指针来指向它,然后根据结构体来操作数据。这样做虽然危险,但是如果保证有精确的协议,这样使用,是完全可以的。而且,通过memcpy这样的函数,对于void*类型的内存块,可以让多个小的数据存储区动态合并到一个大的内存区中,从而构造更加复杂的具有递归性质的结构体来。

让我们发挥这两种语言的各自优势,来构造java的指针吧,让Java也成为一个有指针的语言,尽管它不愿意J

原创粉丝点击