针对c–在Linux或OSX中动态加载库?和linuxc++加载动态库这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展asp.net–Linux或OSX中的WebAPI2.1、dlopen&
针对c – 在Linux或OSX中动态加载库?和linux c++加载动态库这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展asp.net – Linux或OS X中的Web API 2.1、dlopen & dlsys 动态加载库、iOS(OC)中动态加载运行测试代码、linux – ELF动态加载器符号查找排序等相关知识,希望可以帮助到你。
本文目录一览:- c – 在Linux或OSX中动态加载库?(linux c++加载动态库)
- asp.net – Linux或OS X中的Web API 2.1
- dlopen & dlsys 动态加载库
- iOS(OC)中动态加载运行测试代码
- linux – ELF动态加载器符号查找排序
c – 在Linux或OSX中动态加载库?(linux c++加载动态库)
但是在Linux或OSX中会怎么样呢?原因是我想为我的X平台应用程序开发一个插件系统.
谢谢
解决方法
asp.net – Linux或OS X中的Web API 2.1
Could not load type 'System.Web.Http.WebHost.Routing.HttpRouteExceptionHandler' from assembly 'System.Web.Http.WebHost,Version=5.1.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35'.
我这个不在Mono DLL中的东西?是否有可能从Windows获得此功能?
我希望能够完成所有开发Linux和OS X并在Windows Server上运行它.
解决方法
dlopen & dlsys 动态加载库
在读 HAL 相关源码的时候发现这两个函数
简而言之,共享对象通过 dlopen 动态打开动态库的加载完成后,返回一个句柄,通过 dlsym 定位到你需要执行的函数指针然后可以在程序中使用
dlopen -- open a dynamically linked library
dlsym -- get the address of a symbol in a dynamically linked library
例子 void *handle;
int i, *iptr;
int (*fptr)(int);
/* open the needed object */
handle = dlopen("/usr/mydir/libx.so", RTLD_LAZY);
/* find address of function and data objects */
fptr = (int (*)(int))dlsym(handle, "some_function");
iptr = (int *)dlsym(handle, "int_object");
/* invoke function, passing value of integer as a parameter */
i = (*fptr)(*iptr);
参考资料 http://topic.csdn.net/u/20090422/17/2ddcab88-2d50-478a-9b2e-2c2978ad604b.html
http://hi.baidu.com/janefei1603/blog/item/72ae708eed638eda503d923b.html
Additional link: http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html
具体实现
dlopen
基本定义
功能:打开一个动态链接库
包含头文件:
#include <dlfcn.h>
函数定义:
void * dlopen( const char * pathname, int mode );
函数描述:
在 dlopen 的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用 dlclose()来卸载打开的库。
mode:分为这两种
RTLD_LAZY 暂缓决定,等有需要时再解出符号
RTLD_NOW 立即决定,返回前解除所有未决定的符号。
RTLD_LOCAL
RTLD_GLOBAL 允许导出符号
RTLD_GROUP
RTLD_WORLD
返回值:
打开错误返回 NULL
成功,返回库引用
编译时候要加入 -ldl (指定 dl 库)
例如
gcc test.c -o test -ldl
编辑本段
使用 dlopen
dlopen() 是一个强大的库函数。该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。比如 Apache Web 服务器利用这个函数在运行过程中加载模块,这为它提供了额外的能力。一个配置文件控制了加载模块的过程。这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了。
可以在自己的程序中使用 dlopen()。dlopen() 在 dlfcn.h 中定义,并在 dl 库中实现。它需要两个参数:一个文件名和一个标志。文件名可以是我们学习过的库中的 soname。标志指明是否立刻计算库的依赖性。如果设置为 RTLD_NOW 的话,则立刻计算;如果设置的是 RTLD_LAZY,则在需要的时候才计算。另外,可以指定 RTLD_GLOBAL,它使得那些在以后才加载的库可以获得其中的符号。
当库被装入后,可以把 dlopen() 返回的句柄作为给 dlsym() 的第一个参数,以获得符号在库中的地址。使用这个地址,就可以获得库中特定函数的指针,并且调用装载库中的相应函数。
dlsym
dlsym() 的函数原型是
void* dlsym(void* handle,const char* symbol)
该函数在 <dlfcn.h> 文件中。
handle 是由 dlopen 打开动态链接库后返回的指针,symbol 就是要求获取的函数的名称,函数返回值是 void*, 指向函数的地址,供调用使用
取动态对象地址:
#include <dlfcn.h>
void *dlsym(void *pHandle, char *symbol);
dlsym 根据动态链接库操作句柄 (pHandle) 与符号 (symbol), 返回符号对应的地址。
使用这个函数不但可以获取函数地址,也可以获取变量地址。比如,假设在 so 中
定义了一个 void mytest() 函数,那在使用 so 时先声明一个函数指针:
void (*pMytest)(), 然后使用 dlsym 函数将函数指针 pMytest 指向 mytest 函数,
pMytest = (void (*)())dlsym(pHandle, "mytest");
iOS(OC)中动态加载运行测试代码
// TestLoadder.m
// WGTestFramework
//
// Created by liujc on 2017/11/27.
// Copyright © 2017年 liujc. All rights reserved.
//
#import "TestLoadder.h"
#import "TestDataLoader.h"
#import "GlobalVariable.h"
#import "Report.h"
#import "Utils.h"
#import <objc/runtime.h>
#import <UIKit/UIDevice.h>
@implementation TestLoadder
static TestLoadder* _instance=nil;
@synthesize TestProjectVersion=_testProjectVersion;
+(instancetype) shareInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}
+ (id)allocWithZone:(struct _NSZone *)zone
{
@synchronized (self) {
if(_instance==nil){
_instance=[super allocWithZone:zone];
}
}
return _instance;
}
- (id) copyWithZone:(NSZone *)zone
{
return self;
}
- (void)runTest:(NSString *)Classes DefaultClass:(NSString*) defaultClass DefaultMethod:(NSString *) defaultMethod Category:(NSString *)category
{
if(Classes==nil || [Classes length]==0){
NSLog(@"@Classes don''t nil");
return;
}
classesArray=Classes;
defaultClassName=defaultClass;
defaultMethodName=defaultMethod;
testCategory=category;
NSThread *thread=[[NSThread alloc] initWithTarget:self selector:@selector(ThreadRunTestCases) object:nil];
[thread start];
}
- (void) collectTestSummaryAndSendResultToServer{
Report *report=[[Report shareInstance] CreateNewReport];
[report SetValue:@"subject" Value:[GlobalVariable shareInstance].report_title];
[report SetValue:@"sdk_version" Value:self.TestProjectVersion];
[report SetValue:@"platform" Value:[[UIDevice currentDevice] systemVersion]];
[report SetValue:@"startTime" Value:[self dateFormat:startTimeDate]];
[report SetValue:@"endTime" Value:[self dateFormat:endTimeDate]];
int duration=[[NSNumber numberWithDouble:[endTimeDate timeIntervalSince1970]] integerValue]-[[NSNumber numberWithDouble:[startTimeDate timeIntervalSince1970]] integerValue];
[report SetValue:@"duration" Value:[NSString stringWithFormat:@"%@", [self duration_string:duration]]];
[report SetValue:@"tolist" Value:[GlobalVariable shareInstance].tolist];
[report SaveToDisk];
NSData *result_data = [[NSData alloc] initWithContentsOfFile:[GlobalVariable shareInstance].result_path];
TestDataLoader *tdLoader = [[TestDataLoader alloc] init];
NSString *send_result = [tdLoader sendRequest_sync:@"" type:@"post" data:result_data tcfolder:@"report"];
NSLog(@"%@", send_result);
}
- (NSString *)duration_string:(int) duration
{
NSString *str_duration=@"";
int mod=0;
int remainder=0;
int times=60*60*24;
if(duration>times){
mod=duration/times;
duration=duration%times;
if(mod>0){
str_duration=[str_duration stringByAppendingFormat:@"%i days ", mod];
}
}
times=60*60;
if(duration>times){
mod=duration/times;
duration=duration%times;
if(mod>0){
str_duration=[str_duration stringByAppendingFormat:@"%i hours ", mod];
}
}
times=60;
if(duration>60){
mod=duration/times;
duration=duration%times;
if(mod>0){
str_duration=[str_duration stringByAppendingFormat:@"%i minutes ", mod];
}
}
str_duration=[str_duration stringByAppendingFormat:@"%i seconds", duration];
return str_duration;
}
- (NSString *)dateFormat:(NSDate *) date
{
NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
[formatter setTimeStyle:NSDateFormatterShortStyle];
[formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
NSTimeZone *timeZone=[NSTimeZone timeZoneWithName:@"Asia/Beijing"];
[formatter setTimeZone:timeZone];
return [formatter stringFromDate:date];
}
- (void)ThreadRunTestCases{
extern NSString* case_category;
NSArray *classes=[classesArray componentsSeparatedByString:@","];
NSString *default_class_name=defaultClassName;
NSString *method_name=defaultMethodName;
NSString *m_name;
Method meth=nil;
Class tclass=nil;
unsigned int count=0;
objc_property_t *method=nil;
@autoreleasepool {
[[GlobalVariable shareInstance] create_path];
startTimeDate=[NSDate date];
for(NSString *class_name in classes){
if([default_class_name length]>0 && ![default_class_name isEqual:class_name]){
continue;
}
tclass=[[NSClassFromString(class_name) alloc]init];
count=0;
method=class_copyMethodList([tclass class], &count);
for(int i=0;i<count;i++){
meth=method[i];
SEL sel=method_getName(meth);
m_name=[NSString stringWithUTF8String:sel_getName(sel)];
if([m_name hasPrefix:@"test_"]){
if([method_name length]>0){
if ([method_name isEqual:m_name])
{
[tclass performSelector:NSSelectorFromString(m_name)];
}
}
else{
[tclass performSelector:NSSelectorFromString(m_name)];
}
}
}
}
endTimeDate=[NSDate date];
[self collectTestSummaryAndSendResultToServer];
}
sleep(5);
exit(0);
}
@end
linux – ELF动态加载器符号查找排序
解析共享库的符号时,加载器首先搜索“主可执行文件”(让主可执行文件覆盖定义……)或者什么?
解决方法
>主可执行文件通常是“全局”查找范围中的第一个对象.这意味着主可执行文件中定义的符号将覆盖依赖共享库中的符号.使用LD_PRELOAD工具添加的共享对象将添加到主可执行文件后面的全局查找范围中.
>但是,如果正在加载的共享对象使用DF_SYMBOLIC标志,则在该对象中生成的符号引用将在搜索全局查找范围之前查找对象内的定义.
>使用dlopen()打开的共享对象可能有自己的依赖项.如果在调用dlopen()期间未设置RTLD_GLOBAL标志,则会将这些依赖项添加到该对象的查找范围,但不会影响全局查找范围.如果将RTLD_GLOBAL标志传递给dlopen(),则共享对象(及其依赖项)将添加到“全局”查找范围,从而更改后续符号查找的行为.
Ulrich Drepper的指南“How to Write Shared Libraries”建议阅读此主题.
关于c – 在Linux或OSX中动态加载库?和linux c++加载动态库的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于asp.net – Linux或OS X中的Web API 2.1、dlopen & dlsys 动态加载库、iOS(OC)中动态加载运行测试代码、linux – ELF动态加载器符号查找排序等相关知识的信息别忘了在本站进行查找喔。
本文标签: