简体   繁体   English

使用功能名称已在另一个使用的库中定义的库

[英]Using library which has a function name already defined in another used library

I am developing a project in C++ with Qt and OpenCV 3.0. 我正在使用Qt和OpenCV 3.0在C ++中开发一个项目。 When trying to use the face recognition module of OpenCV, I get an error. 尝试使用OpenCV的面部识别模块时,出现错误。

When accessing the file predict_collector.hpp and the class below 当访问文件predict_collector.hpp和下面的类时

class CV_EXPORTS_W PredictCollector {
protected:
    ...
public:
    ...
    CV_WRAP virtual bool emit(const int label, const double dist, const int state = 0); 
};

The compiler links the emit keyword with its definition in Qt, generating this error: 编译器将Qt中的定义与其发出关键字链接,从而产生此错误:

\libs\opencv3.0.0\opencv_contrib-master\modules\face\include\opencv2\face/predict_collector.hpp(77): error C2059: syntax error: 'const'

because 'const' is a keyword in C++ and cannot be passed an argument to the Qt emit function. 因为'const'是C ++中的关键字,不能将参数传递给Qt发射函数。 You see that the compiler treats emit as if it is the Qt version. 您会看到编译器将辐射视为Qt版本。

Noting that emit is a macro function, it is not an ordinary one, so we cannot use namespaces, a you can see in qobjectsdef.h: 请注意,emit是一个宏函数,它不是普通的函数,因此我们无法使用名称空间,您可以在qobjectsdef.h中看到它:

#ifndef QT_NO_EMIT
# define emit
#endif

I tried to make 我试图使

#undef emit 

in the file predict_collector.hpp but it will generate errors in all of the project. 在文件predict_collector.hpp中,但是它将在所有项目中生成错误。

How to resolve this issue? 如何解决这个问题?

Use namespace calls in your code. 在代码中使用名称空间调用。 That allows you to write namespace1::functionX() and namespace2::functionX(). 这样就可以编写namespace1::functionX()namespace2::functionX().

Where that is not possible try adding in 如果不可能,请尝试添加

namespace namespace1{
    //code here
}

or 要么

using namespace
//Code here//

If using these in your own code doesn't fix the error then it may be possible to add this into the relevant OpenCV and Qt files. 如果在您自己的代码中使用它们不能解决错误,则可以将其添加到相关的OpenCV和Qt文件中。

See: https://stackoverflow.com/a/22190519/355177 参见: https : //stackoverflow.com/a/22190519/355177

In short: 简而言之:

You can define the QT_NO_KEYWORDS macro, that disables the “signals” and “slots” macros. 您可以定义QT_NO_KEYWORDS宏,该宏将禁用“信号”和“插槽”宏。

If you use QMake: 如果您使用QMake:

CONFIG += no_keywords 配置+ = no_keywords

If you're using another build system, do whatever it needs to pass -DQT_NO_KEYWORDS to the compiler. 如果您正在使用其他构建系统,请执行将-DQT_NO_KEYWORDS传递给编译器所需的任何操作。

If you want to use Qt "emit" use Q_EMIT. 如果要使用Qt“发出”,请使用Q_EMIT。

That is indeed one of the issues of defining macros (and especially unprefixed macros, the macro in QT should indeed have been defined as QT_EMIT or similar to minimize collisions). 这确实是定义宏的问题之一(尤其是无前缀的宏,QT中的宏确实应该定义为QT_EMIT或类似名称,以最大程度地减少冲突)。

What you will most likely need to do is to undefine the macro before including the OpenCV headed, and then define it back. 您最可能需要做的是在包含OpenCV标题之前取消定义宏,然后重新定义它。 And also do the same on every place the emit is called. 并且在调用发射的每个位置都执行相同的操作。

Namespaces will not likely help here, as the macro "emit" will still be defined and will still clash with the function name. 命名空间在这里可能不太有用,因为宏“ emit”将仍然被定义并且仍与函数名冲突。

Something like this: 像这样:

#ifdef emit
// undef and store emit
#define MY_EMIT_STORE emit
#undef emit
#endif

#include "predict_collector.hpp"

#ifdef MY_EMIT_STORE
// return emit back for QT
#define emit MY_EMIT_STORE
#undef MY_EMIT_STORE
#endif

and on every place emit is called. 并且在每个地方都发出了放射。 The need to return emit back can be avoided, if you include all QT headers before the OpenCV headers and if you do not use the QT emit in your cpp. 如果在OpenCV标头之前包含所有QT标头,并且在cpp中不使用QT标头,则可以避免返回标头。 Then just undefining the emit macro could work: 然后只需取消定义emit宏即可:

// include all QT headers

#ifdef emit
#undef emit
#endif

#include "predict_collector.hpp"

// do not use the QT emit below

Another option (based on your last edit) might be to define the QT_NO_EMIT macro so that the emit will not be defined by QT, before including the QT headers, like: 另一个选择(基于您的上一次编辑)可能是定义QT_NO_EMIT宏,以便在包括QT标头之前不会由QT定义发射,例如:

#define QT_NO_EMIT
// include the QT headers

Or by defining QT_NO_EMIT generally in your compiler flags ("-DQT_NO_EMIT"). 或者通常在编译器标志(“ -DQT_NO_EMIT”)中定义QT_NO_EMIT。

The solution that worked for me is to reorder the order of my included files. 对我有用的解决方案是重新排序我包含的文件的顺序。

I put the #include <opencv2/face.hpp> before any call to any Qt include file. 我将#include <opencv2/face.hpp>放在对任何Qt包含文件的调用之前。 so that the emit keyword will not be defined yet. 因此,尚不定义emit关键字。

And Recursively, if your header containing #include <opencv2/face.hpp> is included in another header file in your project, be careful to put it before any Qt include file, and the same for the second file. 并且递归地,如果包含#include <opencv2/face.hpp>标头包含在项目的另一个标头文件中,请小心地将其放在任何Qt包含文件之前,第二个文件应包含相同的标题。


The important is to make sure to call #include <opencv2/face.hpp> before any call to to the definition of the Qt macro emit . 重要的是要确保在对Qt宏定义的任何调用emit之前先调用#include <opencv2/face.hpp> You will be sure that your code will be compiled without any collision. 您将确保您的代码将被编译而不会发生任何冲突。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM