0%

Cpp搞FbxSDK的坑

摘要

樓下樓上鄰居做愛聲音太大了, 開啓電音 , 更新下博文

簡要記錄搞 Autodesk FbxSDK 時的一些使用套路

0xFF 命令行

  • 使用命令行來與批處理脚本在Windows下快速執行文件的路徑訪問與功能切換

選用cmdline作爲簡單的命令分析工具

  • 優點:

      1. 包含單個.h文件即可使用
      2. 命令添加與讀取簡單
      3. 跨平臺
    
  • 坑:

    1. 在Windows MSVC編譯時需要修改demangle(const std::string& name) 這個函數

      • 修改如下 :
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      static inline std::string demangle(const std::string& name)
      {
      #ifdef _MSC_VER
      // 为MSVC编译器时直接返回name
      return name;
      #elif defined(__GNUC__)
      // 为gcc编译器时, 调用原来的代码
      int status = 0;
      char* p = abi::__cxa_demangle(name.c_str(), 0, 0, &status);
      std::string ret(p);
      free(p);
      return ret;
      #else
      // 其他不支持的编译器需要自己实现这个方法
      #error unexpected c complier (msc/gcc), Need to implement this method for demangle
      #endif
      }
    • 頭部修改為:

      1
      2
      3
      4
      //当编译器非gcc时,不包含cxxabi.h头文件
      #ifdef __GNUC__
      #include <cxxabi.h>
      #endif

0xFE 中文字符處理

  • 使用本地化的 ASCII編碼,以方便從Window讀取本地化路徑

    1
    2
    3
    #include <windows.h>
    // System locale
    setlocale(LC_ALL, "");
  • 從操作系統到FbxSDK時, 由於FbxSDK全部使用UTF-8處理, 因此需要將系統本地的ASCII轉換成UTF-8

  • 從ASCII到UTF-8需要注意先轉換為UNICODE

  • Window在處理文件路徑的時候, 會有兩套API, A代表ASCII字符, W表示寬字符(也就是UNICODE)

  • UTF-8 使用的是Char類型,且可變寬度

    • 以下代碼記錄了ASCII UTF-8 UNICODE之間的相互轉換
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    #pragma once

    #include <string>
    #include <iostream>
    #include <windows.h>
    #include <tchar.h>


    /*
    * Chinese:
    * Outside --> Inside
    * GBK --> UTF8
    *
    * Inside
    * UTF8
    *
    * Inside --> Outside
    * UTF8 --> GBK
    *
    * Windows Path Input
    * UTF8 --> Unicode
    *
    * Windows Path Output
    * Unicode --> UTF8
    *
    */

    namespace GBKConvert
    {

    using namespace std;

    void testWordFunc()
    {
    CHAR* pStr = "中文字测试."; // ANSI编码
    WCHAR* pWStr = L"中文字测试."; // Unicode 宽字节编码
    TCHAR* pTStr = _T("中文字测试."); // 根据_UNICODE定义
    }

    // UTF-8 转 Unicode
    wstring Utf82Unicode(const string& utf8string)
    {
    int widesize = ::MultiByteToWideChar(CP_UTF8, 0, utf8string.c_str(), -1, NULL, 0);
    if (widesize == ERROR_NO_UNICODE_TRANSLATION)
    {
    throw std::exception("Invalid UTF-8 sequence.");
    }
    if (widesize == 0)
    {
    throw std::exception("Error in conversion.");
    }
    std::vector<wchar_t> resultstring(widesize);
    int convresult = ::MultiByteToWideChar(CP_UTF8, 0, utf8string.c_str(), -1, &resultstring[0], widesize);
    if (convresult != widesize)
    {
    throw std::exception("La falla!");
    }
    return std::wstring(&resultstring[0]);
    }

    // Unicode 转 Ascii
    string Unicode2Ascii(wstring& wstrcode)
    {
    int asciisize = ::WideCharToMultiByte(CP_OEMCP, 0, wstrcode.c_str(), -1, NULL, 0, NULL, NULL);
    if (asciisize == ERROR_NO_UNICODE_TRANSLATION)
    {
    throw std::exception("Invalid UTF-8 sequence.");
    }
    if (asciisize == 0)
    {
    throw std::exception("Error in conversion.");
    }
    std::vector<char> resultstring(asciisize);
    int convresult = ::WideCharToMultiByte(CP_OEMCP, 0, wstrcode.c_str(), -1, &resultstring[0], asciisize, NULL, NULL);
    if (convresult != asciisize)
    {
    throw std::exception("La falla!");
    }
    return std::string(&resultstring[0]);
    }

    //UTF-8 转 Ascii
    string Utf82Ascii(string& strUtf8Code)
    {
    string strRet("");
    //先把 utf8 转为 Unicode
    wstring wstr = Utf82Unicode(strUtf8Code);
    //最后把 Unicode 转为 ascii
    strRet = Unicode2Ascii(wstr);
    return strRet;
    }

    // Ascii 转 Unicode
    wstring Ascii2Unicode(string& strascii)
    {
    int widesize = MultiByteToWideChar(CP_ACP, 0, (char*)strascii.c_str(), -1, NULL, 0);
    if (widesize == ERROR_NO_UNICODE_TRANSLATION)
    {
    throw std::exception("Invalid UTF-8 sequence.");
    }
    if (widesize == 0)
    {
    throw std::exception("Error in conversion.");
    }
    std::vector<wchar_t> resultstring(widesize);
    int convresult = MultiByteToWideChar(CP_ACP, 0, (char*)strascii.c_str(), -1, &resultstring[0], widesize);
    if (convresult != widesize)
    {
    throw std::exception("La falla!");
    }
    return std::wstring(&resultstring[0]);
    }

    // Unicode 转 UTF8
    string Unicode2Utf8(wstring& widestring)
    {
    using namespace std;
    int utf8size = ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, NULL, 0, NULL, NULL);
    if (utf8size == 0)
    {
    throw std::exception("Error in conversion.");
    }
    std::vector<char> resultstring(utf8size);
    int convresult = ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, &resultstring[0], utf8size, NULL, NULL);
    if (convresult != utf8size)
    {
    throw std::exception("La falla!");
    }
    return std::string(&resultstring[0]);
    }

    // Ascii 转 UTF8
    string Ascii2Utf8(string& strAsciiCode)
    {
    string strRet("");
    //先把 ascii 转为 unicode
    wstring wstr = Ascii2Unicode(strAsciiCode);
    //最后把 unicode 转为 utf8
    strRet = Unicode2Utf8(wstr);
    return strRet;
    }
    }


0xFD

  • 下次有心情的時候寫

歡迎關注我的其它發布渠道