C语言动态调用与java动态调用 实现对比

1、unix c

通过将源代码编译编译成so动态库,dlopen实现动态加载so库中函数(一般通过配置实现 交易码+so库名+函数名称),并通过对应的函数指针实现dlsym调用后地址转换。

1:创建test.h, test.c文件

//test.h
#ifndef TEST_H_
#define TEST_H_

#include <stdio.h>

void PrintHello();
int Add(int a, int b);

#endif

2:将其编译成动态库

gcc test.c -shared -fPIC -o libtest.so

3:创建主文件main.c

//main.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <signal.h>
#include <errno.h>

//输出错误信息并退出      
void error_quit(const char *str)      
{      
 fprintf(stderr, "%s\n", str);  
 exit(1);      
} 

int main(int argc, char *argv [])
{
 void *plib;      //指向so文件的指针
 typedef void (*FUN_HELLO)();
 typedef int (*FUN_ADD)(int, int);
 FUN_HELLO funHello = NULL;  //函数指针
 FUN_ADD funAdd = NULL;

 //打开so文件
 //为了方便演示,我将库文件和可执行文件放在同一个目录下
 plib = dlopen("./libtest.so", RTLD_NOW | RTLD_GLOBAL);
 if( NULL == plib )
  error_quit("Can't open the libtest.so");

 //加载函数void Hello()
 funHello = dlsym(plib, "Hello");
 if( NULL == funHello )
  error_quit("Can't load function 'Hello'");
 
 //加载函数int Add(int a, int b)
 funAdd = dlsym(plib, "Add");
 if( NULL == funAdd )
  error_quit("Can't load function 'Add'");

 //调用成功加载的函数
 funHello();
 printf("5 + 8 = %d\n", funAdd(5, 8));

 //关闭so文件
 dlclose(plib);

 return 0;
}

4:编译,运行

gcc main.c -o main -ldl
./main

2、java语言通过类Class实现对配置文件中指定的全路径类加载

student类:
public class Student {  
    public void show(){  
        System.out.println("is show()");  
    }  
} 
配置文件以txt文件为例子(pro.txt):
className = cn.fanshe.Student  
methodName = show  

测试类:
import java.io.FileNotFoundException;  
import java.io.FileReader;  
import java.io.IOException;  
import java.lang.reflect.Method;  
import java.util.Properties;  
  
/* 
 * 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改 
 * 我们只需要将新类发送给客户端,并修改配置文件即可 
 */  
public class Demo {  
    public static void main(String[] args) throws Exception {  
        //通过反射获取Class对象  
        Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"  
        //2获取show()方法  
        Method m = stuClass.getMethod(getValue("methodName"));//show  
        //3.调用show()方法  
        m.invoke(stuClass.getConstructor().newInstance());  
          
    }  
      
    //此方法接收一个key,在配置文件中获取相应的value  
    public static String getValue(String key) throws IOException{  
        Properties pro = new Properties();//获取配置文件的对象  
        FileReader in = new FileReader("pro.txt");//获取输入流  
        pro.load(in);//将流加载到配置文件对象中  
        in.close();  
        return pro.getProperty(key);//返回根据key获取的value值  
    }  
}  

总结:

将上面的代码加以扩展可实现一套交易系统的服务入口配置化(入口函数声明时参数固定)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值