簡體   English   中英

MAC:Qt 無法檢測工具包

[英]MAC: Qt Cannot detect toolkit

屏幕

如何使用 Qt 5.12.1/Qt Creator 4.8.1 配置 QT 項目
我需要為 mac os 編譯我的項目。
我嘗試使用 QT Creator,然后,出現以下問題。

或者用下面的命令編譯。

qmake
make

但是,發生以下錯誤。

third_party/wfdbio.cpp:181:5: fatal error: assigning to 'char *' from
      incompatible type 'void *'
    SSTRCPY(wfdbpath, wfdbpath_init);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
third_party/wfdb.h:234:3: note: expanded from macro 'SSTRCPY'
         SALLOC(P, (size_t)strlen(WFDB_tmp)+1,1); strcpy(P, WFDB_tmp); } }
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
third_party/wfdb.h:231:37: note: expanded from macro 'SALLOC'
#define SALLOC(P, N, S) { SFREE(P); SUALLOC(P, (N), (S)) }
                                    ^~~~~~~~~~~~~~~~~~~~
third_party/wfdb.h:230:38: note: expanded from macro 'SUALLOC'
#define SUALLOC(P, N, S) { if (!(P = calloc((N), (S)))) MEMERR(P, (N), (S)); }
                                     ^~~~~~~~~~~~~~~~
1 error generated.
make: *** [objects/wfdbio.o] Error 1

錯誤屏幕 2 當然,我可以使用類型轉換更改一些代碼,例如) char* to void*
但是,有很多宏和代碼,因此,“刪除類型轉換”需要進行很多代碼更改。
當然,我使用了“-fpermissive”標志,並且我的項目是在 Windows 10 上編譯的。

那么,如何在不更改代碼的情況下編譯我的項目?

編輯:

這是我的問題的 MRE:

#include <stdio.h>
#include <stdlib.h> 
int main()
{
    char *buffer;

    printf("How long do you want the string? ");

    buffer = malloc(10);
    // buffer = (char* ) malloc(10);

    return 0;
}

此代碼在 Windows10 Cygwin上編譯。

# At Cygwin, gcc version is
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/7.4.0/lto-wrapper.exe
Target: x86_64-pc-cygwin
Configured with: /cygdrive/i/szsz/tmpp/gcc/gcc-7.4.0-1.x86_64/src/gcc-7.4.0/configure --srcdir=/cygdrive/i/szsz/tmpp/gcc/gcc-7.4.0-1.x86_64/src/gcc-7.4.0 --prefix=/usr --exec-prefix=/usr --localstatedir=/var --sysconfdir=/etc --docdir=/usr/share/doc/gcc --htmldir=/usr/share/doc/gcc/html -C --build=x86_64-pc-cygwin --host=x86_64-pc-cygwin --target=x86_64-pc-cygwin --without-libiconv-prefix --without-libintl-prefix --libexecdir=/usr/lib --enable-shared --enable-shared-libgcc --enable-static --enable-version-specific-runtime-libs --enable-bootstrap --enable-__cxa_atexit --with-dwarf2 --with-tune=generic --enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-graphite --enable-threads=posix --enable-libatomic --enable-libcilkrts --enable-libgomp --enable-libitm --enable-libquadmath --enable-libquadmath-support --disable-libssp --enable-libada --disable-symvers --with-gnu-ld --with-gnu-as --with-cloog-include=/usr/include/cloog-isl --without-libiconv-prefix --without-libintl-prefix --with-system-zlib --enable-linker-build-id --with-default-libstdcxx-abi=gcc4-compatible --enable-libstdcxx-filesystem-ts
Thread model: posix
gcc version 7.4.0 (GCC)

但是,我無法在我的 Mac OS 上編譯。

下面是錯誤代碼。

Ws-Mac:Desktop w$ gcc test.cpp -fpermissive
test.cpp:9:14: error: assigning to 'char *' from incompatible type 'void *'
    buffer = malloc(10);
             ^~~~~~~~~~
1 error generated.
# At Mac OS, gcc version is
Ws-Mac:Desktop w$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Ws-Mac:Desktop w$ 

這是因為 C 和 C++ 處理從void *到 a 的轉換的方式不同。 在 C 中,任何指針類型都可以自由轉換為/從void *轉換而無需強制轉換。 C++ 不允許這樣做,如果您嘗試在沒有強制轉換的情況下進行轉換,則會拋出錯誤。

您示例中的代碼是 C 代碼,但文件名以 .cpp 結尾,因此 gcc 將代碼編譯為 C++。 所以這一行:

buffer = malloc(10);

生成錯誤,因為 C++ 不允許隱式void *轉換。

如果您將文件名從 test.cpp 更改為 test.c,它將編譯干凈。

回到您的 QT 項目,因為 QT 是一個 C++ 庫,您不能只是嘗試將所有代碼編譯為 C 代碼。

如果有這些錯誤的模塊包含 C 代碼,那么您可以將這些模塊的文件名從 .cpp 更改為 .c,並且您需要修改相關的頭文件以在函數聲明周圍添加extern "C" . 如果這些錯誤出現在實際上是 C++ 的模塊中,那么您需要更改代碼以使用static_cast<char*>malloc / calloc / realloc的返回值分配給char *

簡單的答案是“不要在 c++ 中使用malloc ”,如果您使用new代替,問題就會消失,並且作為獎勵,您可以正確初始化類。

如果您確實必須使用malloc ,則無法避免將結果static_cast轉換為適當的類型。

如果你真的不想在任何地方添加靜態轉換,那么這樣的事情可能會奏效:

struct mymalloc
{
    mymalloc(size_t size)
    : data(malloc(size))
    {
    }
    mymalloc(const mymalloc&) = delete;
    mymalloc& operator=(const mymalloc&) = delete;

    void* data;

    template <typename T>
    operator T*()
    {
        return static_cast<T*>(data);
    }
};

int main()
{
    char *buffer = mymalloc(10);
    free(buffer);

    return 0;
}

您甚至可以使用#define malloc mymalloc取得一些成功,但是您需要非常小心,不要這樣做而破壞其他任何東西。

我再說一遍,正確的解決方案是從malloc切換到new並避免所有這些黑客行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM