[英]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
當然,我可以使用類型轉換更改一些代碼,例如) 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.