引用dll报错:error C2491-不允许 dllimport 静态数据成员 的定义

本文主要是介绍引用dll报错:error C2491-不允许 dllimport 静态数据成员 的定义,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题

创建一个QT的dll工程,生成lib、dll文件后,新建一个测试工程,将动态库的头文件、lib文件加入到该工程里,通过头文件引用dll的导出类.

编译测试工程时报错:

1>GeneratedFiles\Release\moc_TestDll.cpp(58): warning C4273: “TestDll::qt_static_metacall”: dll 链接不一致
1>  d:\code\test\vs\qtguiapplication1\qtguiapplication1\generatedfiles\release\../../TestDll.h(26): note: 参见“qt_static_metacall”的前一个定义 (编译源文件 GeneratedFiles\Release\moc_TestDll.cpp)
1>GeneratedFiles\Release\moc_TestDll.cpp(65): warning C4273: “staticMetaObject”: dll 链接不一致

1>  d:\code\test\vs\qtguiapplication1\qtguiapplication1\generatedfiles\release\../../TestDll.h(26): note: 参见“public: static QMetaObject const TestDll::staticMetaObject”的前一个定义 (编译源文件 GeneratedFiles\Release\moc_TestDll.cpp)
1>GeneratedFiles\Release\moc_TestDll.cpp(65): **<u>error C2491</u>**: “TestDll::staticMetaObject”: 不允许 dllimport 静态数据成员 的定义


导出类头文件的代码如下:

#pragma once#include <QtCore/qglobal.h>#ifndef BUILD_STATIC
# if defined(TESTDLL_LIB)
#  define TESTDLL_EXPORT Q_DECL_EXPORT
# else
#  define TESTDLL_EXPORT Q_DECL_IMPORT
# endif
#else
# define TESTDLL_EXPORT
#endifclass TESTDLL_EXPORT TestDll :public QObject
{Q_OBJECT
public:TestDll();~TestDll();...int f(int param);};

查看出错的代码行是:Q_OBJECT

而Q_OBJECT是一个宏定义:

#define Q_OBJECT \
public: \QT_WARNING_PUSH \Q_OBJECT_NO_OVERRIDE_WARNING \static const QMetaObject staticMetaObject; \virtual const QMetaObject *metaObject() const; \virtual void *qt_metacast(const char *); \virtual int qt_metacall(QMetaObject::Call, int, void **); \QT_TR_FUNCTIONS \
private: \Q_OBJECT_NO_ATTRIBUTES_WARNING \Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \QT_WARNING_POP \struct QPrivateSignal {}; \QT_ANNOTATE_CLASS(qt_qobject, "")

其中QT_TR_FUNCTIONS又是一个宏定义:

# define QT_TR_FUNCTIONS \
static inline QString tr(const char *s, const char *c = Q_NULLPTR, int n = -1) \{ return staticMetaObject.tr(s, c, n); } \
QT_DEPRECATED static inline QString trUtf8(const char *s, const char *c = Q_NULLPTR, int n = -1) \{ return staticMetaObject.tr(s, c, n); }

由此可见,之所以编译会报错是因为导出类的类体里的Q_OBJECT定义了静态的内联函数,而这是被VS禁止的:

'identifier' : definition of dllimport function not allowed
Data, static data members, and functions can be declared as dllimports but not defined as dllimports.

错误描述:不允许定义dllimport修饰的函数

数据,静态数据成员和函数在声明时可以使用dllimport修饰,但定义时禁止使用dllimport修饰。

 

解决方法

去掉类TestDll之前的TESTDLL_EXPORT,编译就通过了。

附微软官方文档说明:

https://docs.microsoft.com/zh-cn/cpp/error-messages/compiler-errors-1/compiler-error-c2491?view=vs-2019

Compiler Error C2491
2016/11/04

'identifier' : definition of dllimport function not allowed
Data, static data members, and functions can be declared as dllimports but not defined as dllimports.
To fix this issue, remove the __declspec(dllimport) specifier from the definition of the function.
The following sample generates C2491:

// C2491.cpp
// compile with: /c
// function definition
void __declspec(dllimport) funcB() {}   // C2491

// function declaration
void __declspec(dllimport) funcB();   // OK

这篇关于引用dll报错:error C2491-不允许 dllimport 静态数据成员 的定义的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/491567

相关文章

豆包 MarsCode 不允许你还没有女朋友

在这个喧嚣的世界里,爱意需要被温柔地唤醒。为心爱的她制作每日一句小工具,就像是一场永不落幕的浪漫仪式,每天都在她的心田播撒爱的种子,让她的每一天都充满甜蜜与期待。 背景 在这个瞬息万变的时代,我们都在寻找那些能让我们慢下来,感受生活美好的瞬间。为了让这份浪漫持久而深刻,我们决定为女朋友定制一个每日一句小工具。这个工具会在她意想不到的时刻,为她呈现一句充满爱意的话语,让她的每一天都充满惊喜和感动

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

Jenkins 插件 地址证书报错问题解决思路

问题提示摘要: SunCertPathBuilderException: unable to find valid certification path to requested target...... 网上很多的解决方式是更新站点的地址,我这里修改了一个日本的地址(清华镜像也好),其实发现是解决不了上述的报错问题的,其实,最终拉去插件的时候,会提示证书的问题,几经周折找到了其中一遍博文

【Python报错已解决】AttributeError: ‘list‘ object has no attribute ‘text‘

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法2.1 方法一:检查属性名2.2 步骤二:访问列表元素的属性 三、其他解决方法四、总结 前言 在Python编程中,属性错误(At

DBeaver 连接 MySQL 报错 Public Key Retrieval is not allowed

DBeaver 连接 MySQL 报错 Public Key Retrieval is not allowed 文章目录 DBeaver 连接 MySQL 报错 Public Key Retrieval is not allowed问题解决办法 问题 使用 DBeaver 连接 MySQL 数据库的时候, 一直报错下面的错误 Public Key Retrieval is

JavaSE(十三)——函数式编程(Lambda表达式、方法引用、Stream流)

函数式编程 函数式编程 是 Java 8 引入的一个重要特性,它允许开发者以函数作为一等公民(first-class citizens)的方式编程,即函数可以作为参数传递给其他函数,也可以作为返回值。 这极大地提高了代码的可读性、可维护性和复用性。函数式编程的核心概念包括高阶函数、Lambda 表达式、函数式接口、流(Streams)和 Optional 类等。 函数式编程的核心是Lambda

浙大数据结构:树的定义与操作

四种遍历 #include<iostream>#include<queue>using namespace std;typedef struct treenode *BinTree;typedef BinTree position;typedef int ElementType;struct treenode{ElementType data;BinTree left;BinTre

vue 父组件调用子组件的方法报错,“TypeError: Cannot read property ‘subDialogRef‘ of undefined“

vue 父组件调用子组件的方法报错,“TypeError: Cannot read property ‘subDialogRef’ of undefined” 最近用vue做的一个界面,引入了一个子组件,在父组件中调用子组件的方法时,报错提示: [Vue warn]: Error in v-on handler: “TypeError: Cannot read property ‘methods