必威体育Betway必威体育官网
当前位置:首页 > IT技术

跨平台相关

时间:2019-10-02 10:13:28来源:IT技术作者:seo实验室小编阅读:90次「手机版」
 

跨平台

转载请注明出处。https://rhirufxmbcyj.gitlab.io

strdup 和 _strdup 的使用及区别

二者区别:

strdup是POSIX,_strdup是windows特定。 在Unix上,使用的strdup。

平台宏定义

在不同操作系统的lib库名字不同的,为了让程序可以多平台,需要在宏定义中判断当前运行操作系统编译器的类型,动态调整。

  • 操作系统判定:
Windows:   WIN32   _WIN32
linux:   linux   __linux  __linux__
MAC:     __APPLE__
Solaris:   __sun
  • 编译器判定:
Borland:             __BORLANDC__

Codeplay vectorC:    __VECTORC__

digital Mars:        __DMC__

Gnu:                 __GNUC__

Intel:               __INTEL_COMPILER

Microsoft:           _MSC_VER

Pathscale:           __PATHSCALE__

Symantec:            __SYMANTECC__

Watcom:              __WATCOMC__
  • 操作系统位数判定:
Linux_x32:  __i386__
Linux_x64:  __x86_64__
Windows:    _WIN64 定义了就是x64  没定义就是x32

x86:    _M_IX86    __INTEL__   __i386__

x86-64: _M_X64     __x86_64__  __AMD64

IA64:   __IA64__

DEC Alpha: __ALPHA__

Motorola Power PC: __POWERPC__

Any little endian: __LITTLE_ENDIAN__

Any big endian: __BIG_ENDIAN__

pthread相关

#include <pthread.h>

pthread并非Linux系统的默认库,而是POSIX线程库,在Linux中将其作为一个库来使用,因此加上 -lpthread(或-pthread)以显式链接该库。函数执行错误信息作为返回值返回。

  • 创建线程
int pthread_create(
pthread_t *tidp,
const pthread_attr_t *attr,
(void*)(*start_rtn)(void*),
void *arg);

第一个参数为指向线程标识符的指针

第二个参数用来设置线程属性。

第三个参数是线程运行函数的起始地址。

最后一个参数是运行函数的参数。

  • 等待线程结束
int pthread_join(pthread_t thread, void **retval);
  • 互斥锁
    • 初始化 pthread_mutex_t 动态创建的需要用pthread_mutex_init( )初始化,释放内存必须用pthread_mutex_destroy( )销毁。静态创建的用PTHREAD_MUTEX_INITIALZER赋值。
    • 锁上互斥锁  pthread_mutex_lock( )
    • 解锁互斥锁  pthread_mutex_unlock( )
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *fun1(void *arg)
{
    pthread_mutex_t *temp = (pthread_mutex_t *)arg;
    pthread_mutex_lock(temp);
    for(int i=0;i<5;i++)
    {
        sleep(5);
    }
    pthread_mutex_unlock(temp);
    return 0;
}
void *fun2(void *arg)
{
    pthread_mutex_t *temp = (pthread_mutex_t *)arg;
    pthread_mutex_lock(temp);
    pthread_mutex_unlock(temp);
    return 0;
}

int main()
{
    pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
    pthread_t thread1,thread2;
    pthread_create(&thread1,NULL,fun1,&mu);
    pthread_create(&thread2,NULL,fun2,&mu);
    pthread_join(thread1,NULL);
    pthread_join(thread2,NULL);
    pthread_mutex_destroy(&mu);
    return 0;
}
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/
void *thread1(void *);
void *thread2(void *);
int i=1;
int main(void)
{
    pthread_t t_a;
    pthread_t t_b;
    pthread_create(&t_a,NULL,thread1,(void *)NULL);/*创建进程t_a*/
    pthread_create(&t_b,NULL,thread2,(void *)NULL); /*创建进程t_b*/
    pthread_join(t_a, NULL);/*等待进程t_a结束*/
    pthread_join(t_b, NULL);/*等待进程t_b结束*/
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    exit(0);
}

void *thread1(void *junk)
{
    for(i=1;i<=6;i++)
    {
        pthread_mutex_lock(&mutex);/*锁住互斥量*/
        printf("thread1: lock %d/n", __LINE__);
        if(i%3==0){
            printf("thread1:signal 1 %d/n", __LINE__);
            pthread_cond_signal(&cond);/*条件改变,发送信号,通知t_b进程*/
            printf("thread1:signal 2 %d/n", __LINE__);
            sleep(1);
        }
        pthread_mutex_unlock(&mutex);/*解锁互斥量*/
        printf("thread1: unlock %d/n/n", __LINE__);
        sleep(1);
    }
}

void *thread2(void *junk)
{
    while(i<6)
    {
        pthread_mutex_lock(&mutex);
        printf("thread2: lock %d/n", __LINE__);
        if(i%3!=0){
            printf("thread2: wait 1 %d/n", __LINE__);
            pthread_cond_wait(&cond,&mutex);/*解锁mutex,并等待cond改变*/
            printf("thread2: wait 2 %d/n", __LINE__);
        }
        pthread_mutex_unlock(&mutex);
        printf("thread2: unlock %d/n/n", __LINE__);
        sleep(1);
    }
}

跨平台踩坑

  • printf("%s",a);a不能为NULL否则会报错
  • Visual GDB(后面使用VG表示) 调试某一个测试程序。VG不能指定编译和调试某一个程序(比如gtest程序),

    如果需要调试指定的程序需要在VisualGDB Project Properties ->Debug setting ->debug->Debugged executable 中设置启动的程序就可以调试指定的程序了

  • VG运行制定gtest 在VisualGDB Project Properties ->Debug setting ->debug->Main executable arguments 中指定

    gtest的名称就可以运行指定路径的gtest --gtest_filter=case2.*

  • linux long 和 long long 都是8字节,windows下的long是4字节,需要把windows下的long改成int使用
  • visualGDB打开的工程中不能识别include目录,需要在 工程->右键属性->配置属性->VC++目录->包含目录中手动把src目录添加进去,否则inlcude的时候需要使用…去寻找完整路径。

    例如 不配置的话 #include "base/base.h"就不能识别到,需要使用#include “…/base/base.h”

  • CMakeLists.txt中依赖静态库语句中,被依赖的库名需放在依赖库名后

    例如 target_link_libraries(main test1 test2 test3 test4)

    test2依赖test4,test4就需要放test2后边

  • linux和mac中没有类似windows中的_DEBUG宏

linux下动态库去符号(仅适用动态库):

原文:https://blog.csdn.net/passers_b/article/details/7582535

推荐第二种方法

1、使用GCC 的C++ visibility 支持。

把__attribute__ ((visibility (“default”))) 放置在你希望导出的struct,class,function的声明处,然后修改你的GCC构建参数,使用 -fvisibility=hidden 参数编译每一个源代码文件。GCC编译源代码文件的visibility默认属性是public,所以默认所有符号都导出来了,设置为hidden后然后在需要导出的地方加__attribute__ ((visibility (“default”))),以达到控制导出符号的目的。在跨平台代码的编写中,常使用下面类似的宏定义来简化上述过程。

#if defined _WIN32 || defined __cygwin__
  #ifdef buildING_DLL
    #ifdef __GNUC__
      #define DLL_PUBLIC __attribute__ ((dllexport))
    #else
      #define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.
    #endif
  #else
    #ifdef __GNUC__
      #define DLL_PUBLIC __attribute__ ((dllimport))
    #else
      #define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.
    #endif
  #endif
  #define DLL_local
#else
  #if __GNUC__ >= 4
    #define DLL_PUBLIC __attribute__ ((visibility ("default")))
    #define DLL_LOCAL  __attribute__ ((visibility ("hidden")))
  #else
    #define DLL_PUBLIC
    #define DLL_LOCAL
  #endif
#endif
extern "C" DLL_PUBLIC void function(int a);
class DLL_PUBLIC SomeClass
{
   int c;
   DLL_LOCAL void privateMethod();  // Only for use within this DSO
public:
   Person(int _c) : c(_c) { }
   static void foo(int a);
};

2、使用链接参数 --retain-symbols-file 控制静态符号表,–version-script 控制动态符号表,后面都是接含有导出符号的文件的名字。这两个参数在移植windows下的动态库很有用,windows下的DEF文件能控制导出符号,我们可以在linux下的构建脚本中解析DEF生成一个导出符号文件,然后作为retain-symbols-file,version-script的参数。

编译链接方法:gcc a1.c -shared -o liba1.so -Wl,–retain-symbols-file=a1.sym -Wl,–version-script=a1.map

a1.sym写法:控制.symtab节
func_1
func_3
a1.map写法:控制.dynsym节
{
global:
  func_1;
  func_2;
local: *;
};

一般编译会加-s将.symtab节删除掉,过删除的话就可以不加a1.sym

相关阅读

网站跨平台,我们能做什么?

最近比较关注WEB页面在不同平台的呈现,于是浏览了多家门户网站分别在PC端、IPAD端、手机端呈现差异,这过程中逐步对网站跨平台呈现

Qt 跨平台简单界面设计工具

参考文档:https://blog.csdn.net/shenziheng1/article/details/52556763、http://www.mamicode.com/info-detail-2428809.html、百

跨平台通用账号系统|浅析Facebook、Instagram、Messeng

账号系统则好比人体的血液循环系统,起着运输、沟通、交流的作用。如果将APP比喻成人体,那么该APP的主功能就好比是人体的心脏,给予AP

跨平台的多层次网络营销传播

几天前,笔者微信收到了一则朋友圈发来的消息,打开一看原来是清明节期间在广州地王广场所举办的一场&ldquo;地王广场流浪动物领养日&

分享到:

栏目导航

推荐阅读

热门阅读