动态连接,就是把这些相通的功能、函数都放到一种特殊形式的windwos可执行文件中(dll),生成一个DLL的时候,程序员需要写出,其中包含那些函数需由其他程序来访问。这个过程叫做对函数的“导出”。
创建windows程序的时候,专门的连接程序对程序的对象文件进行扫描,并生成一个列表,列出那些调用的函数在那个DLL那个位置,指定各个函数所在位置的过程叫做对函数的“导入”,当程序运行的时候,一旦要求用到执行文件内部没有的函数,windows就会自动装载动态连接库,使应用程序可以访问这些函数。此时,每个函数的地址都会解析出来,并且以动态的方式连接到程序里——这便是术语“动态连接”的由来。
我个人觉得DLL还有一个好处就是保密性和跨语言平台性,因为DLL中是二进制01串,所以增加了代码的保密性。在使用DLL时我们无需知道其具体细节是什么,它是如何实现某某功能的,而只用关心怎么去用它。在有时用一种语言实现一个功能十分困难,但如果换一种语言的话实现起来就简单得多。在这种情况之下DLL也可以派上用场。
我的这个程序也就是用上了后面这一点。由于java不能调用Win_Api所以我想直接用Win_Api来实现一些功能就行不通了。但是我们可以借助DLL这个媒介来实现刚刚那个不可能的功能。
以下就是cmdDLL的实现过程:
首先,在我们写好了一个Server.java程序(接下来它将调用cmdDLL.dll的函数 CMD)后,用javac Server.java 先生成一个Server.class文件,然后接下来就是用这个Server.class文件生成一个Server.h文件(javah Server.h)。此时对Server.java文件的操作到一段落。
其次,我们需要写一个.cpp文件。在这个.cpp程序中我们将先前已经弄好的Server.h要包含在这个cmdDLL.cpp文件中,因为Server.h文件是接下来Server.java中要调用的CMD者个函数的声明。
#include < stdlib.h >
#include < string .h >
JNIEXPORT void JNICALL Java_Server_CMD (JNIEnv * env, jclass,jstring a )
{
const char * str = env -> GetStringUTFChars(a, 0 );
char str_1[ 100 ] = { 0 };
strncpy(str_1,str,strlen(str) - 1 );
char str_2[ 100 ] = " > out.txt " ;
strcat(str_1,str_2);
system(str_1);
}
对cmdDLL.cpp的操作如下:
link cmdDLL.obj / dll
然后就可以生成一个名为
cmdDLL.Dll中的void CMD(String args)这个函数的功能:
(1)接受上层的一个string args 然后将其类型转换后得到一个const char* str。
(2)由于我们需要向Client回显cmd中的内容所以这里我们就需要将回显先转移到out.txt中
strncpy(str_1,str,strlen(str) - 1 );
char str_2[ 100 ] = " > out.txt " ;
strcat(str_1,str_2);
然后将这个以文本的形式存到out.txt(准备给Client回显)中。
最后就是要实现str_1这个指令了(在cmd之下),我所使用的方法是int system(const char* args)。比如现在位置是D:/,然后str_1 = “dir > out.txt”,那么其将在Server端显示cmdDLL的DLL文件。