{eval=Array;=+count(Array);}

问答专栏Q & A COLUMN

如何在windows上编译linux可用的动态链接库?

glumesglumes 回答0 收藏1
收藏问题

3条回答

Jokcy

Jokcy

回答于2022-06-28 09:59

1、背景

最近的性能测试中,压测的某些接口返回的数据是一个复杂的json格式的字符串,而后续的接口中又需要把这个字符串修改后作为入参,自己处理起来比较麻烦。于是想到了把cjson编译成动态链接库在loadrunner的脚本中调用。另外,由于实际压测用的是部署在linux上的负载机,还需要再编译一个linux上的动态链接库。这样在调试时使用windows平台的dll,而在压测时使用linux平台的so。 先附上我编译好的动态链接库,可以直接在loadrunner中使用http://download.csdn.net/download/ultrahook/10126401

2、cjson

cjson是一个开源的json库,它的优势在于完全用c实现,因此适用性相当广,用在loadrunner中也是毫无压力。它的git主页是https://github.com/DaveGamble/cJSON。

3、windows平台

  1. 打开vsual studio(我用的是vs2015,其他版本也可以,codeblock也没问题,随你喜欢),新建一个win32程序,程序类型选择dll,附加选项选择空项目。
  2. 把cJSON.c和cJSON.h拖到工程里。
  3. 设置编译选项为release、x86(重要!),编译。
  4. 将编译出来的cjson.dll放到loadrunner脚本的根目录下,然后在菜单File-Add file to script,添加cjson.dll。
  5. 在代码中加载cjson.dll,然后就可以使用cjson的函数了。先尝试一下,

    • 1
    • 2
    • 3

    注意这里cjson_Version返回的是指针,但loadrunner认为是int,所以要显式转成指针,不然编译不通过。

  6. 再看cjson解析字符串的函数。它的用法如下:

    • 1
    • 2

    这里需要用到cJSON.h中声明的结构体cJSON,但直接引用cJSON.h在loadrunner中编译不过。这个也有解决办法,把cJSON.h中cJSON这个结构体的定义代码复制到action的顶部就可以了,如图 cJSON.h中其他的变量或者宏也可以,如果编译时报错,复制过来就可以了。

4、Linux平台

下面再编译一个linux平台上的动态链接库,用在linux负载机上。 cjson的代码中带了MakeFile,也有cmake,可以直接编译。但如果linux系统是64位的,则默认编译的是64位的so,无法被loadrunner加载,会提示“wrong ELF class: ELFCLASS64”。我们需要手动修改MakeFile,让它编译一个32位的so。 1. 修改cJSON源码根目录下的MakeFile 打开MakeFile,分别在29、31、93、96行,增加-m32,如图 2. 在源码根目录下执行

  • 1
  • 2

如果出现提示“fatal error: sys/cdefs.h: No such file or directory”,需要再装一个依赖库

  • 1
  • 2

3. 编译成功后,会得到名为libcjson.so.1.6.0的动态链接库。把它复制到loadrunner脚本的根目录下,同样菜单File-Add file to script,增加到脚本中。 4. 在脚本中加载so,这步和windows上是一样的。这样脚本就可以在linux下运行了。linux上安装负载机可以参考我的另一篇文章http://blog.csdn.net/ultrahook/article/details/78524182。

  • 1
  • 2

5、遗留问题

最后有个遗留问题,loadrunner似乎不支持平台宏,我想用宏控制,在windows下加载dll,linux下加载so,但没有找到解决方法。

评论0 赞同0
  •  加载中...
douzifly

douzifly

回答于2022-06-28 09:59

首先谢邀。

windows上的动态链接库一般是指dll文件,linux上的动态链接库一般是指so文件。

so文件是一个共享库,用来动态链接的shared object,下面示范怎么在windows平台上编译so文件,实质是模拟linux使用GCC环境来编译so文件,工具采用vs2008。

1 打开vs2008,新建一个win32的控制台项目,然后新建mathunit,c和mathunit.h两个文件,文件的内容如下所示:

mathunits.c

  1. #include "mathunits.h"
  2. #include "time.h"
  3. #include "stdio.h"
  4. #include "stdlib.h"
  5. int add(int a,int b)
  6. {
  7. return a + b;
  8. }
  9. int sub(int a,int b)
  10. {
  11. return a - b;
  12. }
  13. void WriteSysLog(char *str)
  14. {
  15. char buf[512];
  16. long MAXLEN = 10*1024*1024;//10MB
  17. time_t timep;
  18. FILE *fp = NULL;
  19. struct tm *p;
  20. time(&timep);
  21. p = localtime(&timep);
  22. memset(buf,0,sizeof(buf));
  23. sprintf(buf,"%d-%d-%d %d:%d:%d : ",(1900+p->tm_year),(1+p->tm_mon),
  24. p->tm_mday,p->tm_hour, p->tm_min, p->tm_sec); //星期p->tm_wday
  25. strcat(buf,str);
  26. strcat(buf," ");
  27. fp = fopen("./syslog.log","r");
  28. if(fp==NULL)
  29. {
  30. fp = fopen("./syslog.log","w+");
  31. }
  32. else
  33. {
  34. fseek(fp,0,2);
  35. if(ftell(fp) >= MAXLEN)
  36. {
  37. fclose(fp);
  38. fp = fopen("./syslog.log","w+");
  39. //大于10MB则清空原日志文件
  40. }
  41. else
  42. {
  43. fclose(fp);
  44. fp = fopen("./syslog.log","a");
  45. }
  46. }
  47. fwrite(buf,1,strlen(buf),fp);
  48. fflush(fp);
  49. //fsync(fileno(fp));
  50. fclose(fp);
  51. }

mathunits.h

  1. #ifndef MATHUNITS_H
  2. #define MATHUNITS_H
  3. int add(int a,int b);
  4. int sub(int x,int y);
  5. void WriteSysLog(char *str);
  6. #endif

然后在该项目的主函数(main)中进行调用测试。(注意vs2008中的main函数跟别的不太一样)

  1. #include "stdafx.h"
  2. #include "stdlib.h"
  3. #include "mathunits.h"
  4. int _tmain(int argc, _TCHAR* argv[])
  5. {
  6. int c = add(7,9);
  7. printf("c = %d ",c);
  8. c = sub(8,19);
  9. printf("c = %d ",c);
  10. WriteSysLog("test log out.");
  11. system("pause");
  12. return 0;
  13. }

在编译开始之前要将vs2008设为C的编译。下面使用GCC进行编译:

1 运行CyqWin.bat设置编译路径到上面mathunits.h和mathunits.c目录。

2 将.c文件编译为.o文件 gcc -c mathunits.c


3 接着将o文件进行打so文件 gcc -shared -fPCI -o libdyunits.so mathunits.o

评论0 赞同0
  •  加载中...
piglei

piglei

回答于2022-06-28 09:59

起码得有个GCC吧

评论0 赞同0
  •  加载中...

相关问题

最新活动

您已邀请0人回答 查看邀请

我的邀请列表

  • 擅长该话题
  • 回答过该话题
  • 我关注的人
向帮助了您的网友说句感谢的话吧!
付费偷看金额在0.1-10元之间
<