c++: definition of dllimport function not allowed, building with visual studio 2010

17,859

Solution 1

"User macros" in VS property sheets have nothing to do with preprocessor macros. Put TRIALDLL_EXPORT into the property sheet's section C/C++ > Preprocessor > Preprocessor Definitions

"User macros," which can only be defined in property sheets, allow you to create your own "variables" usable in Visual Studio properties, similar to the built-in ones $(TargetName), $(SolutionDir) etc.

Solution 2

Put

#error Where is my macro?

in the #else block of the header. Then experiment with the project settings or the #define until you get it right. Did you perhaps only add the property sheet to one configuration? Did you put the #define at the very top of the file? Do you have any PCH stuff that causes it to ignore your settings? And so on.

Solution 3

As said in this Microsoft article, you cannot apply the __declspec(dllimport) keyword to implement a function. You should use it only in the declaration. For example:

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

    // function definition
    void funcB() {
        //funcB code
    }
Share:
17,859
springRoll
Author by

springRoll

Updated on June 26, 2022

Comments

  • springRoll
    springRoll almost 2 years

    I'm using visual studio 2010 to build a .dll. I wrote up a trial as:

    // 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
    

    And the triallDLL.cpp file:

    // 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
    

    With these two files in the project, I added a property sheet to the project through visual studio 2010 property manager and added TRIALDLL_EXPORT to user macros. After all these, the nice Intellisense gives me error for each function defined in the .cpp file and complains "error: a function declared 'dllimport' may not be defined". So it appears that Intellisense doesn't find TRIALDLL_EXPORT defined. I thought it might make a difference if I actually build the project, but the result suggests the same error: "error C2491: 'new_MyMathFuncs' : definition of dllimport function not allowed". Then it is clear that the macro TRIALDLL_EXPORT is still not defined in compiling time.

    After failing to add macro through visual studio, I also tried putting code line: #define TRIALDLL_EXPORT in trialDLL.cpp but it didn't help either. I wonder what's the proper way to do this? How do I inform the compiler that the micro is defined so that TRIALDLL_API evaluates to dllexport rather than dllimport?

    Also, if I can build the .dll successfully, is there any systematic way to test/verify the functionality of the .dll?

    Thanks for any help in advance! (Although I know it's an issue here on stackoverflow to put appreciation in the question, I feel myself impolite not to do so. Forgive me for any inefficiency caused by these lines.)

  • springRoll
    springRoll almost 11 years
    Thanks! This works perfectly! By the way, for my curiosity, what does "User macros" do then?
  • Angew is no longer proud of SO
    Angew is no longer proud of SO almost 11 years
    @springRoll They're "variables" for properties you can set in Visual Studio. Like the built-in ones $(TargetName), $(SolutionDir) etc. Property sheets allow you to create your own.
  • springRoll
    springRoll almost 11 years
    Thanks! It works if the #define is put on the very top of the .cpp file. What I did was putting it after the #include in the .cpp file. Can I ask why does it make a difference?
  • Sebastian Redl
    Sebastian Redl almost 11 years
    Macros are defined from the point where they are #defined until the point where they are #undefed (or the end of the translation unit). If you put the #define below the #include, the macro won't be defined in the area of your header.
  • springRoll
    springRoll almost 11 years
    Sorry for the stupid question, I didn't ask myself before I asked you. I figured it out myself when I had a rest minutes ago. Thank you very much for the detailed explanation!