struct dso_st {
DSO_METHOD *meth;
/*
* Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS doesn't use
* anything but will need to cache the filename for use in the dso_bind
* handler. All in all, let each method control its own destiny.
* "Handles" and such go in a STACK.
*/
STACK_OF(void) *meth_data;
CRYPTO_REF_COUNT references;
int flags;
/*
* For use by applications etc ... use this for your bits'n'pieces, don't
* touch meth_data!
*/
CRYPTO_EX_DATA ex_data;
/*
* If this callback function pointer is set to non-NULL, then it will be
* used in DSO_load() in place of meth->dso_name_converter. NB: This
* should normally set using DSO_set_name_converter().
*/
DSO_NAME_CONVERTER_FUNC name_converter;
/*
* If this callback function pointer is set to non-NULL, then it will be
* used in DSO_load() in place of meth->dso_merger. NB: This should
* normally set using DSO_set_merger().
*/
DSO_MERGER_FUNC merger;
/*
* This is populated with (a copy of) the platform-independent filename
* used for this DSO.
*/
char *filename;
/*
* This is populated with (a copy of) the translated filename by which
* the DSO was actually loaded. It is NULL iff the DSO is not currently
* loaded. NB: This is here because the filename translation process may
* involve a callback being invoked more than once not only to convert to
* a platform-specific form, but also to try different filenames in the
* process of trying to perform a load. As such, this variable can be
* used to indicate (a) whether this DSO structure corresponds to a
* loaded library or not, and (b) the filename with which it was actually
* loaded.
*/
char *loaded_filename;
CRYPTO_RWLOCK *lock;
};
meth:指出了操作系统相关的动态库操作函数。
meth_data:堆栈中存放了加载动态库后的句柄。
reference:引用计数,DSO_new的时候置1,DSO_up_ref时加1,DSO_free时减1。
当调用DSO_free时,只有当前的references为1时才真正释放meth_data中存放的句柄。
flag:与加载动态库时加载的文件名以及加载方式有关,用于DSO_ctrl函数。
DSO_convert_filename:当加载动态库时会调用DSO_convert_filename函数来确定所加载的文件。而DSO_convert_filename函数会调用各个系统自己的convert函数来获取这个文件名。
对于flag有三种种操作命令:设置、读取和或的关系,对应定义如下:
#define DSO_CTRL_GET_FLAGS 1
#define DSO_CTRL_SET_FLAGS 2
#define DSO_CTRL_OR_FLAGS 3
而flag可以设置的值有如下定义:
#define DSO_FLAG_NO_NAME_TRANSLATION 0x01
#define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY 0x02
#define DSO_FLAG_UPCASE_SYMBOL 0x10
#define DSO_FLAG_GLOBAL_SYMBOLS 0x20
意义说明如下:
DSO_FLAG_NO_NAME_TRANSLATION
加载的文件名与指定的文件名一致,不加后缀.dll(windows)或.so(linux或unix)。
DSO_FLAG_NAME_TRANSLATION_EXT_ONLY
加载的文件名会加上lib串,比如用户加载eay32,真正加载时会加载libeay32(适用于linux或unix)。
DSO_FLAG_UPCASE_SYMBOL
适用于OpenVMS。
DSO_FLAG_GLOBAL_SYMBOLS
适用于unix,当在unix下调用加载函数dlopen时,参数会被或上RTLD_GLOBAL。
ex_data:扩展数据,没有使用。
name_converter::指明了具体系统需要调用的名字计算函数。
loaded_filename:指明了加载动态库的全名。
实例:
#include "/usr/include/openssl/opensslconf.h"
#include <openssl/dso.h>
#include <openssl/bio.h>
#include <stdio.h>
typedef BIO *(*BIO_newx) (const BIO_METHOD *method);
typedef int (*BIO_freex)(BIO *method);
int main()
{
DSO *d;
void (*f1)();
void (*f2)();
BIO *test;
BIO_newx BIOnew;
BIO_freex BIOfree;
d=DSO_new();
if (d == NULL) {
printf("DSO_new err \n");
return -1;
}
//d=DSO_load(d,"/home/haisi/zy/test/libeay32.dll",NULL,0);
d=DSO_load(NULL,"/usr/local/openssl/lib/libcrypto.so.1.1",NULL,0);
if (d == NULL) {
printf("DSO_load err\n");
return -1;
}
f1=DSO_bind_func(d,"BIO_new");
f2=DSO_bind_func(d,"BIO_free");
BIOnew=(BIO *(*)(const BIO_METHOD *))f1;
BIOfree=(int (*)(BIO *method))f2;
test=BIOnew(BIO_s_file());
BIO_set_fp(test,stdout,BIO_NOCLOSE);
BIO_puts(test,"abd\n\n");
BIOfree(test);
DSO_free(d);
return 0;
}
通过: nm -D libcrypto.so.1.1 > lso.txt 查看so中的函数