qt能封装动态库让所有的平台都能vc调用qt动态库起来吗

您所在的位置: &
解析 QT 静态库和动态库
解析 QT 静态库和动态库
Qt Creator是跨平台的 Qt IDE, Qt Creator 是 Qt 被 Nokia 收购后推出的一款新的轻量级集成开发环境,Qt Creator 功能包括项目生成向导、高级的 C++ 代码编辑器、浏览文件及类的工具、集成了 Qt Designer、Qt Assistant、Qt Linguist、图形化的 GDB 调试前端,集成 qmake 构建工具等。
QT中静态库的生成与使用
一. 静态库的生成
1. 测试目录: lib
2. 源码文件名: mywindow.h, mywindow.cpp, 类MyWindow继承于QPushButton, 并将文字设置为&I'm in class MyWindow&;
3. 编写项目文件: mywindow.pro
TEMPLATE&=&lib&CONFIG&&&+=&staticlib&
4. 生成Makefile:
5. 编译生成静态库libmywindow.a
二. 静态库的使用
1. 测试目录: test
2. 将mywindow.h与libmywindow.a拷贝至test目录下
3. 编写main.cpp, 包含头文件mywindow.h, 并调用MyWindow类
4. 编写项目文件: test.pro
注意加上库路径与库文件名:
LIBS&+=&-L&./&-lmywindow&
5. 生成Makefile: qmake
6. 编译: make
7. 运行: ./test
QT中共享库的生成与使用
如果你打开一些 应用程序的目录,你会发现有很多程序的 exe 文件都很小,大约几百K 的样子,并且目录中不仅仅只有一个 exe 文件,还包含着一大堆 dll 文件。这些 dll 其实就是一些共享库,所谓共享库,其实就是一些动态链接库,能够由程序在运行时进行动态加载的库。既然说是共享,那就是说,这些库不仅仅自己的程序可以使用,并且其他程序也可以使用,例如某些通用算法。
如果你发布一下自己编写的 Qt 程序,也会看到很多系统的共享库,就是那些 QtGui.dll 之类的东西。或许你会说,我写的程序没有同其他应用共享的库,就不需要这些了吧!其实不然。因为共享库的一个好处是可以动态加载,也就是说,如果你需要升级程序,那么就要简单的替换掉这个 dll 就好了,不需要要求用户重新安装全部文件。当然,这些 dll 也是有缺点的:动态加载的东西肯定会比静态编译的东西效率低一些。不过在现在的硬件环境下,这点性能损失已经可以忽略不计了。
我们还是使用 Qt Creator。在创建工程的时候,我们选择下面的
Library 一项,然后点击 OK。
在接下来的对话框中,有一个下拉列表,分别是 Shared Library(共享库),Statically Linked Library(静态链接库)和 Qt 4 Plugin(Qt 4 插件)。我们选择第一个共享库,后面的步骤中会要求选择加入哪几个 Qt 模块,和前面一样,选择自己需要的部分,最后完成工程的创建。
我们会看到 QtCreator 已经帮我们创建好了一些文件。其中有一个 {projectName}_global.h 的文件是 QtCreator 替我们创建的。下面我们就从这个 {projectName}_global.h 开始:
#ifndef&LIB_GLOBAL_H&&& &#define&LIB_GLOBAL_H&&& &#include&/qglobal.h&&&& &#if&defined(LIB_LIBRARY)&&& &#&&define&LIBSHARED_EXPORT&Q_DECL_EXPORT&&& &#else&&& &#define&LIBSHARED_EXPORT&Q_DECL_IMPORT&& &#endif&&& &#endif&//&LIB_GLOBAL_H&&&
这个文件中只是定义了两个宏 LIBSHARED_EXPORT,注意这里的 LIB 就是我的工程名字。如果定义了 LIB_LIBRARY,LIBSHARED_EXPORT 定义为 Q_DECL_EXPORT,否则定义为 Q_DECL_IMPORT。看这个名字,就知道这就是把对象导出的语句了。下面我们来编写一个窗口(如果你希望这么做,不要忘记在创建工程时勾选 QtGui 模块,默认是不勾选的):
&#ifndef&LIB_H&&& &&#define&LIB_H&&&&& &&#include&&&&&&& &&#include&&lib_global.h&&&& &&class&LIBSHARED_EXPORT&MainWindow&:&public&QMainWindow&{&&& &&public:&& &&&&&&&MainWindow(QWidget&*parent&=&0);&& &&};&& &#endif&//&LIB_H& &
&&& &#include&&lib.h&&&& &MainWindow::MainWindow(QWidget&*parent) &:&QMainWindow(parent)&&& &{&& &&}&&&
代码很简单,就是创建一个 MainWindow。同前面的代码唯一不同的是,在头文件中,使用了 LIBSHARED_EXPORT 这个宏。你可以简单的把它理解成,我需要把这个类 MainWindow 导出。所谓导出,就是将其编译成一个 dll 文件之后,其他的类可以使用这个导出类。好了,下面和原来一样,编译一下这个工程。在 debug 文件夹下你得到的是一个 lib.dll 文件和 liblib.a。后者是 Linux 下使用的库,这里不再详述。
好了,我们要去使用这个 dll 了。新建另外一个工程,需要吧 .pro 文件修改一下:
TARGET&=&test&&& &TEMPLATE&=&app&&&& &SOURCES&+=&main.cpp&&& &INCLUDEPATH&+=&../&&&& &LIBS&+=&../debug/lib.dll&&
首先,我们添加了 INCLUDEPATH 这一行。这一行就是为了让我们的 test 项目可以找到 lib.h 和 lib_global.h 这两个文件,你需要把这里的路径替换成符合你的工程的路径。LIBS 这一行则需要告诉编译器(注意,这里是编译器!)到哪里去找到这个 dll 文件。然后我们编写 main.cpp:
#include&/QApplication&&& &&#include&&lib.h&&&&& &&int&main(int&argc,&char&*argv[])&&& &&{&&& &&&&&&QApplication&a(argc,&argv);&&& &&&&&&MainWindow&w;&& &&&&&&w.show();&& &&&&&&return&a.exec();&& &&}&&&
注意,我们使用了 lib.h,但是这个文件并没有在 HEADERS 里面声明,Qt 实际上就是从 INCLUDEPATH 这里去找到这个文件。MainWindow 在新建的 test 工程中并没有声明,那么它在哪里呢?当然就是在我们编译出来的 lib.dll 里面啦!我们知道,在链接的时候编译器需要找到实现入口,也就是必须定位到这个 dll,这就是由这个 LIBS 指定的地方。
最后编译运行一下这个 exe 文件,怎么样?哦,如果你照我说的做了的话,你应该得到一个错误:找不到 lib.dll。怎么会找不到呢?不是使用 LIBS 指定了吗?请注意,我们强调了,这个指定是编译期的。dll 是动态链接库,也就是说,在 exe 运行的时候需要找到这个库。运行时查找的顺序是:当前路径 -& 系统路径(通常是 system32)。所以,要把我们先前生成的这个 lib.dll 复制到 exe 所在目录,然后直接双击一下这个 exe 文件。一个窗口出来了!有什么区别吗?运行起来是没有区别的,但是我们知道,这个窗口是在这个 dll 里面实现的!我们想往窗口里面加个按钮?没问题,那就加吧!加完之后重新编译一个新的 dll,复制到 exe 文件夹覆盖旧的,修改就完成啦!我们不需要修改这个 exe 了。
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&&&的更多文章
移动异构计算是相对于同构计算来说的,同构计算就是使用同一个处
既然强大的Android Studio来了,有什么理由不去用呢?
七夕,是让人听起来就觉得美好的日子,牛郎织女鹊桥相
PC互联网巨头百度、腾讯和阿里,通过在移动互联网投资
谷歌在新品发布会上正式发布了传闻已久的Android 4.3
本书既能够成为读者的理论支持,又可以作为构建可靠的、可伸缩的、可维护的并发程序的技术支持。本书并不仅仅提供并发API的清单
Windows Phone专家
Android开发专家
51CTO旗下网站linux下qt调用C 语言编写的动态链接库
怎么用qt在linux中编写并使用动态链接库
如何用qt在linux中编写并使用动态链接库?想在linux中写动态链接库,貌似在linux中叫共享库。。
共享库叫libmy.so
程序如下:
#ifndef&LIBMY_H
#define&LIBMY_H
#include&"libmy_global.h
qt调用Linux下自定义的动态链接库有关问题
qt调用Linux下自定义的动态链接库问题我在Linux下用C写了个动态链接库,而且用C写了个测试函数可以正常使用。http://blog.csdn.net/qianguozheng/article/details/6786505但是我改由Qt写了个测试函数的时候C/C++ code
#include &lt
Linux/Unix
linux上怎么编写动态链接库
linux下如何编写动态链接库
1.编写库的头文件和源文件.
2.把所有涉及到的源文件用如下方式编译为目标文件:
# g++/gcc -g -c -fPIC
-o library1.o library1.cpp
# g++/gcc -g -c -fPIC
-o library2.o
delphi中怎么调用vc编写的动态链接库
delphi中如何调用vc编写的动态链接库!现有一个用vc写的动态链接库DrawDll.dll,其中的一个导出函数为:extern &C& _declspec(dllexport) void OnDll_Draw(CDC *pDC,CRect rc,BOOL showreseau);我现在需要
怎么使用Qt编写调试C语言程序
如何使用Qt编写调试C语言程序?在学习使用Qt编写C语言程序,由于是编程初学者,所以有很多困惑。使用Qt的时候就不知道应该如何编写C语言程序了,写好程序如何进行“编译连接”?请大家指点一下,不胜感激。解决方案Qt写C语言?是QtCreator写C语言么?
解决方案写好代码,.proqmake就完了
关于在linux上使用Qt编写CAN通讯程序
关于在linux下使用Qt编写CAN通讯程序之前有用过在网上找的第三方串口类,进行串口通讯过,知道里面有一些串口的基本功能,以及Windows串口类和Linux串口类。目前我有几个疑惑:1,之前Windows串口类和Linux串口类都是对操作系统底层串口文件进行操作,串口读写,设置波特率,数据位等等。那么我现在想写
关于在linux停使用Qt编写CAN通讯程序
关于在linux下使用Qt编写CAN通讯程序之前有用过在网上找的第三方串口类,进行串口通讯过,知道里面有一些串口的基本功能,以及Windows串口类和Linux串口类。
目前我有几个疑惑:
1,之前Windows串口类和Linux串口类都是对操作系统底层串口文件进行操作,串口读写,设置波特率,数据位等等。那么我现在
Linux/Unix
怎么用QT调用linux系统的指令
如何用QT调用linux系统的指令想用QT调用linux里的指令,指令要求光驱弹出然后收回,怎样能够实现。最好能用QT做两个GUI按钮,一个弹出,一个收回。怎么样编写程序啊,哪位高手能帮个忙,本人第一次接触,是菜鸟啊,请哪位大神帮帮我解决方案
cdrom.hC/C++ code
#include &lt
请问一下用QT调用动态链接库,回调函数如何用
请教一下用QT调用动态链接库,回调函数怎么用在mainwindow里面调用动态库,动态库有一个回调函数,就是动态库收到数据以后通过回调函数把数据传给我,这个回调函数要怎么调用mainwindow里面的函数,让回调函数一接收到数据,我就可以立刻处理?C/C++ code
Perl/Python
如何用python调用一个C语言编写的CGI
怎么用python调用一个C语言编写的CGI啊最好是django模型下的哈!我菜鸟,实在不懂哈,望高人指点解决方案
http://docs.python.org/c-api/index.html
个人觉得可以这样,第一种接楼上提供的手册中的将C程序做为python的扩展模块;第二种可以将C程序封装为dll
Linux/Unix
Linux C语言程序的设计 Makefile文件编写解决思路
Linux C语言程序的设计 Makefile文件编写将下面的程序分成多个子程序(输入数据,交换数据,辗除法,输出结果4个子程序),书写makefile文件进行编译和链接,实验报告中要打印源代码和makefile文件。 &输入两个正整数m和n,利用辗除法,求其最大公约数和最小公倍数。& main
Linux/Unix
linux 圆桌面应用程序和web应用程序编写常用的语言
linux 桌面应用程序和web应用程序编写常用的语言1.linux版本这么多,各个版本有什么优缺点及区别。2.该如何选择linux版本。3.桌面应用程序常用的开发语言及开发环境4.web应用程序常用的开发语言及环境5.有谁在linux下用过C#(Mono),感觉怎么样。解决方案
1.参见http
qt 调用linux系统命令修改系统时间,该怎么处理
qt 调用linux系统命令修改系统时间源码:void MainWindow::pushButton_clicked(){ &
str1 = &date -s 04/30/2012&; &
system(str1.toLatin1().data
用Qt调用linux命令打包的有关问题
用Qt调用linux命令打包的问题~比如:tar zcvf /root/m_test.tar.gz /home/m_test . 这样打包压缩后,解压出来就是一个home目录,下面再有个m_test文件夹。而实际上我只是要将home目录下的m_test打包,解压出来就只有一个m_test文件夹,有什么方法实现没有?先
linux停Qt调用c++编译的动态库
linux下Qt调用c++编译的动态库如题,调用c语言编译的库成功了,然后尝试调用c++编译的so,&不成功,哪个大神可以帮帮忙?
提示几行代码最好。谢谢大家
******************************************
助手提示的操作方式是不是只能在windows下使用
文章评论 以下网友留言只代表其个人观点,不代表本网站的观点和立场。二次元同好交流新大陆
扫码下载App
汇聚2000万达人的兴趣社区下载即送20张免费照片冲印
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
& & & 由于不是很熟悉QT中动态链接库的建立过程,就参考网上的方法实现了标准C++链接库的建立,并没有采用QT中的方法,但是这个建立的动态链接库其他程序可以调用的。& & &1.1 首先新建个C++library工程, File-&New-&Other Project-&C++ Library&之后选择shared library之后就新建了三个文件,如果我的文件名为my_lib,则三个文件为:my_lib.h, my_lib_global.h, my_lib.cpp, 由于我使用的是标准C++来建立动态链接库,只是让QT环境编译生成,故my_lib_global.h可以删除,把其余的两文件清空,输入以下内容:my_lib.h#ifndef MY_LIB_H #define MY_LIB_H
extern "C" int add(int x, int y);
#endif // MY_LIB_H my_lib.cpp#include "my_lib.h"
int add(int x, int y) {
return x+y; } 之后运行,弹出如下界面框:&点击cancel,之后在你的debug目录下就会生成一个my_lib.dll的文件,现在我们的动态链接库就建立完毕。2.链接库的使用首先使用QT自己的链接库打开方式,即使用QLibrary类,我是新建一个工程Lib_test,这个工程就是个简单的界面,主要是两个按钮,用来一些简单的显示,代码如下:Widget.h#ifndef WIDGET_H #define WIDGET_H
#include &QtGui/QWidget& #include &QVBoxLayout& #include &QPushButton& #include &QLibrary&
class Widget : public QWidget {
Widget(QWidget *parent = 0);
~Widget();
QPushButton *button1;
QPushButton *button2;
#endif // WIDGET_H Widget.cpp#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent) {
QVBoxLayout *VBLayout = new QVBoxLayout(this);
button1 = new QPushButton();
button2 = new QPushButton();
VBLayout-&addWidget(button1);
VBLayout-&addWidget(button2);
QLibrary test("my_lib.dll");
if(test.load())
typedef int (*Add)(int x, int y);
add = (Add)test.resolve("add");
i = add(3, 2);
button1-&setText(QString::number(i, 10));
if(test.unload())
button2-&setText(tr("Free succeed!"));
button2-&setText(tr("Free failed!"));
button1-&setText(tr("Load failed!"));
Widget::~Widget() {
} main.cpp#include &QtGui/QApplication& #include "widget.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
return a.exec(); }之后编译运行(记住把上面生成的my_lib.dll)复制到该工程的目录下,还有debug目录下,运行结果如下:&。之后就是在其他开发环境中测试,我用DEVC++新建一个程序test.cpp代码如下:#include &stdio.h& #include &windows.h&&#include &windef.h& &int main()&{
typedef int (*Add)(int, int);
//定义一个函数指针
bool flag =
HINSTANCE hdll = NULL;
// 定义一个句柄
hdll = LoadLibrary("my_lib.dll");
//打开链接库
if(hdll == NULL)
printf("Load library error!\n");
system("pause");
add = (Add)GetProcAddress(hdll, "add");
//获取函数
if(add == NULL)
printf("GetProcAddress error!\n");
system("pause");
printf("3 + 2 = %d\n", add(3, 2));
flag = FreeLibrary(hdll);
//释放链接库
if(flag == 0)
printf("Free library error!\n");
system("pause");
system("pause");
& } 运行时把my_lib.dll拷贝到文件所在目录下,编译运行如下:整个的动态链接库生成及使用过程结束。欢迎指教!^_^&
阅读(3828)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'QT中动态链接库的建立,以及在QT中的引用,C++程序中的引用',
blogAbstract:'& & & 首先感谢我的室友xqb的帮助,确实他平时也给了我很多的帮助。& & & 1.我们首先讲解QT中动态链接库的建立:& & & 由于不是很熟悉QT中动态链接库的建立过程,就参考网上的方法实现了标准C++链接库的建立,并没有采用QT中的方法,但是这个建立的动态链接库其他程序可以调用的。& & &1.1 首先新建个C++library工程, File-&New-&Other Project-&C++ Library',
blogTag:'qt,c++,动态链接库',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:7,
permalink:'blog/static/',
commentCount:1,
mainCommentCount:1,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}您所在的位置: &
详解 QT 源码之 QLibrary 跨平台调用动态库实现
详解 QT 源码之 QLibrary 跨平台调用动态库实现
本文介绍将会介绍 QT 源码之 QLibrary 跨平台调用动态库实现,在内容中,将会讨论Qt是如何封装这两种不同的调用动态库的方法。先看内容。
详解 QT 源码之 QLibrary 跨平台调用动态库实现是本文要讲解的内容,在不同同台上动态库的使用,先来看内容。
1、win下动态库调用有关的函数包括:
(1)LoadLibrary,装载动态库。
(2)GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。
(3)FreeLibrary,释放动态链接库。
2、unix上与动态库调用有关的函数包括:
(1)_打开动态链接库:dlopen,函数原型void *dlopen (const char *filename, int flag);
dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。
(2)取函数执行地址:dlsym,函数原型为: void *dlsym(void *handle, char *symbol);
dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。
(3)关闭动态链接库:dlclose,函数原型为: int dlclose (void *handle);
dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。
(4)动态库错误函数:dlerror,函数原型为: const char *dlerror(void); 当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。
我们来分析下Qt的源代码,看看Qt是如何封装这两种不同的调用动态库的方法。
下面是我用vc编写的一个动态库中的函数add:
extern&&C&&__declspec(dllexport)&int&__stdcall&add(int&a,int&b) &{ &&&&&return&a+b; &}&
下面我就用QLibrary来调用一下:
QLibrary&lib(&QtDllTest.dll&); &if&(lib.load()) &{ &&&&&typedef&int(*AddFunction)(int&a,int&b); &&&&&AddFunction&Add=(AddFunction)lib.resolve(&add&); &&&&&if&(!Add) &&&&&{ &&&&&&&&&cout&failed&; &&&&&} &&&&&else &&&&&{ &&&&&&&&int&m; &&&&&&&&m=Add(1,1);&//来个计算1+1 &&&&&&&&cout&result:&; &&&&&} &&&&&lib.unload(); &} &else &{ &&&&&cout&failed&; &}&
首先将目录切换到QTDIR\src\corelib\plugin,这里面就是QLibrary实现的源代码,打开qlibrary_p.h(熟悉了Qt的常用手法,就知道,这就是QLibrary内部实现的代码),可以看到
bool&load_sys(); &bool&unload_sys(); &void&*resolve_sys(const&char&*);&
三个函数。在qlibrary.cpp中可以找到调用这三个函数的地方
bool&QLibrary::load&()调用了load_sys; &bool&QLibrary::unload&()调用了unload_sys; &void&*&QLibrary::resolve&(&const&char&*&symbol&)调用了resolve_sys&
但是并没有找到这三个函数的实现,这是这么回事呢?
打开QTDIR\src\corelib\plugin\plugin.pri文件,
win32&{ &&SOURCES&+=&plugin/qlibrary_win.cpp &} &unix&{ &&SOURCES&+=&plugin/qlibrary_unix.cpp &}&
原来如此啊。
我们仔细看下qlibrary_win.cpp文件,load_sys函数调用了LoadLibrary,unload_sys调用了FreeLibrary,resolve_sys调用了GetProcAddress。
而在qlibrary_unix.cpp文件中,各种linux平台又分好多种。但是基本上load_sys调用了dlopen,unload_sys调用了dlclose,resolve_sys调用了dlsym。
在HPUX中dlopen对应shl_load,dlclose对应shl_unload,dlsym对应shl_findsym。
原来QLibrary就是这样实现不同平台动态库的调用。
小结:详解 QT 源码之 QLibrary 跨平台调用动态库实现的内容介绍完了,希望本篇文章对你有所帮助!【编辑推荐】【责任编辑: TEL:(010)】
关于&&&&的更多文章
移动异构计算是相对于同构计算来说的,同构计算就是使用同一个处
既然强大的Android Studio来了,有什么理由不去用呢?
App定价是开发者不可忽视的部分,它是确保应用高能见
微信自引入语音短信功能用户量爆发之后,发展状况一直
Windows Phone开发创建吸引人、带给人快乐并保留用户
本书深入浅出地说明了如何利用.NET、Flash及XML来辅助Flash富媒体应用程序的开发。
本书首先介绍了Flash影片应用程序与.NET应用
Windows Phone专家
Android开发专家
51CTO旗下网站}

我要回帖

更多关于 vc调用qt动态库 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信