クロスプラットフォーム関連

23767 ワード

転載は出典を明記してください.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はLinuxシステムのデフォルトライブラリではなく、POSIXスレッドライブラリであり、Linuxではライブラリとして使用されるため、-lpthread(または-pthread)を加えてライブラリを明示的にリンクします.関数実行エラーメッセージは、戻り値として返されます.
  • スレッド
  • を作成
    int pthread_create(
    pthread_t *tidp,
    const pthread_attr_t *attr,
    (void*)(*start_rtn)(void*),
    void *arg);
    

    最初のパラメータは、スレッド識別子を指すポインタです.2番目のパラメータは、スレッドのプロパティを設定するために使用されます.3番目のパラメータは、スレッド実行関数の開始アドレスです.最後のパラメータは、関数を実行するパラメータです.
  • スレッド終了待ち
  • 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 
    #include 
    #include 
    #include 
    
    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 
    #include 
    #include 
    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 test 1 test 2 test 3 test 4)test 2はtest 4に依存し、test 4はtest 2の後ろ
  • を置く必要がある
  • linuxとmacにはwindowsのようなものはありません.DEBUGマクロ
  • linuxの下のダイナミックライブラリの脱記号(ダイナミックライブラリのみ):


    原文:https://blog.csdn.net/passers_b/article/details/7582535
    第2の方法を推奨する
    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を使用して動的シンボルテーブルを制御し、後にはエクスポートシンボルを含むファイルの名前が続く.この2つのパラメータはwindowsの下のダイナミックライブラリを移植するのに役立ち、windowsの下のDEFファイルはエクスポート記号を制御することができ、linuxの下の構築スクリプトでDEFを解析してエクスポート記号ファイルを生成し、retain-symbols-file、version-scriptのパラメータとして使用することができます.コンパイルリンク方法:gcc a 1.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節は削除し、削除しすぎるとa 1を追加しなくてもよい.sym