【问题标题】:c++: definition of dllimport function not allowed, building with visual studio 2010c++:不允许定义 dllimport 函数,使用 Visual Studio 2010 构建
【发布时间】:2013-06-21 15:56:30
【问题描述】:

我正在使用 Visual Studio 2010 构建一个 .dll。我写了一个试验:

// trialDLL.h
#ifndef TRIALDLL_H_
#define TRIALDLL_H_

// ... MyMathFuncs class definition omitted

#ifdef __cplusplus
extern "C"{
#endif

#ifdef TRIALDLL_EXPORT
#define TRIALDLL_API __declspec(dllexport)
#else
#define TRIALDLL_API __declspec(dllimport)
#endif

TRIALDLL_API MyMathFuncs* __stdcall new_MyMathFuncs(double offset);
TRIALDLL_API void __stdcall del_MyMathFuncs(MyMathFuncs *myMath);
TRIALDLL_API double __stdcall MyAdd(MyMathFuncs* myMath, double a, double b);
// some other similar stuff

#ifdef __cplusplus
}
#endif

#endif

以及triallDLL.cpp文件:

// trialDLL.cpp
#include "trialDLL.h"

TRIALDLL_API MyMathFuncs* __stdcall new_MyMathFuncs(double offset)
{
    return new MyMathFuncs(offset);
}

TRIALDLL_API void __stdcall del_MyMathFuncs(MyMathFuncs *myMath)
{
    delete myMath;
}

TRIALDLL_API double __stdcall MyAdd(MyMathFuncs *myMath, double a, double b)
{
    return myMath->Add(a, b);
}
// ... some other definitions

有了项目中的这两个文件,我通过visual studio 2010属性管理器在项目中添加了一个属性表,并在用户宏中添加了TRIALDLL_EXPORT。毕竟,漂亮的 Intellisense 给了我在 .cpp 文件中定义的每个函数的错误,并抱怨“错误:可能未定义声明为 'dllimport' 的函数”。因此,Intellisense 似乎没有找到 TRIALDLL_EXPORT 定义。我认为如果我实际构建项目可能会有所不同,但结果表明同样的错误:“错误 C2491:'new_MyMathFuncs':不允许定义 dllimport 函数”。那么很明显宏TRIALDLL_EXPORT在编译时仍然没有定义。

在通过visual studio添加宏失败后,我也尝试将代码行:#define TRIALDLL_EXPORT放入trialDLL.cpp,但它也没有帮助。我想知道这样做的正确方法是什么?如何通知编译器定义了 micro 以便 TRIALDLL_API 计算为 dllexport 而不是 dllimport

另外,如果我可以成功构建 .dll,是否有任何系统的方法来测试/验证 .dll 的功能?

提前感谢您的帮助! (虽然我知道在 stackoverflow 上将赞赏放在问题中是一个问题,但我觉得自己不这样做是不礼貌的。请原谅我因这些行造成的效率低下。)

【问题讨论】:

    标签: c++ visual-studio-2010 dll macros


    【解决方案1】:

    VS 属性表中的“用户宏”与预处理器宏无关。将TRIALDLL_EXPORT 放入属性表部分C/C++ > Preprocessor > Preprocessor Definitions

    “用户宏”只能在属性表中定义,允许您创建自己的可在 Visual Studio 属性中使用的“变量”,类似于内置的 $(TargetName)$(SolutionDir) 等。

    【讨论】:

    • 谢谢!这完美!顺便问一下,为了我的好奇心,“用户宏”是做什么的?
    • @springRoll 它们是可以在 Visual Studio 中设置的属性的“变量”。像内置的$(TargetName)$(SolutionDir) 等。属性表允许您创建自己的。
    【解决方案2】:

    #error Where is my macro?
    

    在标题的#else 块中。然后尝试项目设置或#define,直到你做对了。您是否可能只将属性表添加到一种配置?您是否将#define 放在文件的最顶部?您是否有任何 PCH 内容导致它忽略您的设置?以此类推。

    【讨论】:

    • 谢谢!如果将#define 放在.cpp 文件的最顶部,它就可以工作。我所做的是将它放在 .cpp 文件中的 #include 之后。我能问一下为什么会有所不同吗?
    • 宏定义从它们为#defined 的点到它们为#undefed 的点(或翻译单元的结尾)。如果将#define 放在#include 下方,则不会在标题区域中定义宏。
    • 对不起这个愚蠢的问题,在我问你之前我没有问自己。几分钟前我休息的时候自己想通了。非常感谢您的详细解释!
    【解决方案3】:

    正如Microsoft article 中所说,您不能应用__declspec(dllimport) 关键字来实现功能。你应该只在声明中使用它。例如:

        // function declaration
        void __declspec(dllimport) funcB();
    
        // function definition
        void funcB() {
            //funcB code
        }
    

    【讨论】:

      【解决方案4】:

      代码看起来没问题,如果实际定义了 TRIALDLL_EXPORT,它必须工作。您很可能以某种方式搞砸了(例如将其设置为不同的配置或仅用于一个文件)或没有重建。

      如果您完全迷路了,请询问预处理器的输出,然后查看。与define一样,根本不可能有dllimport,错误也是不可能的。

      编辑:我刚刚注意到你写了_我还尝试将代码行:#define TRIALDLL_EXPORT in_trialDLL.cpp。我以为你把它放在标题的顶部进行试用。首先尝试一下,看看它是否正常工作。找到合适的位置后就可以删除了。

      【讨论】:

        猜你喜欢
        • 2010-12-25
        • 2014-04-03
        • 1970-01-01
        • 2012-05-27
        • 2012-08-18
        • 2011-05-12
        • 2011-04-08
        • 2012-08-17
        • 1970-01-01
        相关资源
        最近更新 更多