bluetiger9 / SmtpClient-for-Qt

An SMTP Client writen in C++ for Qt. Allows applications to send emails (MIME with text, html, attachments, inline files, etc.) via SMTP. Supports SSL and SMTP authentication.
https://github.com/bluetiger9/SmtpClient-for-Qt/wiki
GNU Lesser General Public License v2.1
456 stars 227 forks source link

Class SmtpClient deriving QObject cannot use SMTP_MIME_EXPORT when importing DLL #118

Closed StEvUgnIn closed 1 year ago

StEvUgnIn commented 2 years ago

SMTP_MIME_EXPORT works perfectly for compiling the dynamic library under Windows (SmtpMime2.dll) but it fails for us when we use the same header (smtpclient.h) to link against our libraries.

The only solution we have is to to remove SMTP_MIME_EXPORT (containing Q_DECL_IMPORT).

bluetiger9 commented 2 years ago

Under Windows, when used as library import the SMTP_MIME_EXPORT macro from the headers files will resolve to:

#define Q_DECL_IMPORT __declspec(dllimport)

which I think is needed when importing stuff from DLL-s.

My understanding is that you trying to link SmtpClient library against an another shared library (DLL), right?

Normally the SmtpClient library is linked against an application. I never tried to link against an another shared library (DLL), so the compiler specific attributes on DLL imports may differ.

In case you figure out how this should work, please let me know. I think we could add a new flag in smtpmime_global.h to handle this case.

StEvUgnIn commented 2 years ago

I am not trying to link against another library.

QtCore already has macros that resolves to Q_DECL_IMPORT and Q_DECL_EXPORT in core library that is Q_CORE_EXPORT in <qglobal.h>

Have you tried to compile the library and link it under Windows 11?

bluetiger9 commented 2 years ago

I haven't compiled the library under Windows for a while, but I did it today (on Windows 10).

It worked with the latest QT 6 install, with MinGW and QT Creator. I complied the library and one of the examples / demos.

One issue I found is a typo in the the example's .pro file. Seems like the library under Windows should be included as -lSMTPMime2. (see the latest commit for this fix)

I'm not sure if the above issue is related to what you are experiencing, but if you can tell what you're doing in more details maybe I can help.

StEvUgnIn commented 2 years ago

I am compiling using either CMake 3.23.2 and Qt 6.2.4 latest LTS version under Windows 11.

Windows is case unsensitive in general, but looking at the build system, you should write -lSmtpMime2.

I am sorry but this does not solve the issue we are encountering.

My colleague is compiling using MinGW and I am compiling with VS2019.

Actually, this a linking issue.

I experienced compiling your library with my workstation and also in CircleCI (Windows VS2019, macos clang++, linux g++).

bluetiger9 commented 2 years ago

What your .pro file looks like?

StEvUgnIn commented 2 years ago
LIBS += \
    -lSmtpMime2

It works with under all platforms.

bluetiger9 commented 2 years ago

It works with under all platforms.

Except Windows 11, I assume... :wink:

What is the exact error message you are getting, when linking against the library?

According to the documentation (https://doc.qt.io/qt-6/sharedlibrary.html) having SMTP_MIME_EXPORT on exported symbols is correct. When used in a client app this translates to Q_DECL_IMPORT / __declspec(dllimport), which should be fine. I'm not really sure what happens on you setup under Windows 11.

StEvUgnIn commented 2 years ago

Error C2491 'SmtpClient::staticMetaObject': definition of dllimport static data member not allowed

https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2491?f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(C2491)%26rd%3Dtrue&view=msvc-170

StEvUgnIn commented 2 years ago
// FIXME Import/Export Win32 DLL
class /*SMTP_MIME_EXPORT*/ SmtpClient : public QObject
{
    Q_OBJECT
    Q_ENUMS (AuthMethod SmtpError ConnectionType ClientState)
    ...

This is the only way that works for me.

bluetiger9 commented 2 years ago

Error C2491 'SmtpClient::staticMetaObject': definition of dllimport static data member not allowed

Hmm, interesting...

Looks like CMake has some to feature to auto-generate export headers for DLL-s: https://cmake.org/cmake/help/latest/module/GenerateExportHeader.html

Could you try this feature with CMake and the VS compiler?

INCLUDE(GenerateExportHeader)
ADD_LIBRARY(SmtpMime2
    SHARED
        ...
    )

GENERATE_EXPORT_HEADER(SmtpMime2) 

I would be interested what the generated export headers (*_export.h) looks like. We could use this to adjust src/smtpmime_global.h, so that the VS compiler is happy about it. 🙂

1319191773 commented 1 year ago

Hello I also encountered this problem with QT6 qmake in Windows 10 Prompt content for error: C2491: SmtpClient::staticMetaObject': definition of dllimport static data member not allowed

StEvUgnIn commented 1 year ago

I don't understand this error TBH. AFAIK the macro Q_CORE_EXPORT already does the job of SMTP_MIME_EXPORT.

I defined it as such in src/smtpmime_global.h:

#define SMTP_MIME_EXPORT Q_CORE_EXPORT

But this change is not critical to solve this issue.

It might be related to your compiler. Are you using MinGW (G++) or Visual C++ 2019?

StEvUgnIn commented 1 year ago

@bluetiger9 I consider this issue as unresolved. Did you try with Windows 11?