2

I am following this guide to send email in c++ . You can download the header files : easendmailobj.tlh and easendmail object at here

#include "stdafx.h"
#include <iostream>
#include "easendmailobj.tlh"
using namespace EASendMailObjLib;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    //string email = "randomemail1@gmail.com";

    ::CoInitialize( NULL );

    IMailPtr oSmtp = NULL;
    oSmtp.CreateInstance( "EASendMailObj.Mail");
    oSmtp->LicenseCode = _T("TryIt");

    // Set your gmail email address
    oSmtp->FromAddr = _T("randomemail1@gmail.com");

    // Add recipient email address
    oSmtp->AddRecipientEx( _T("randomemail2s@hotmail.com"), 0 );

    // Set email subject
    oSmtp->Subject = _T("simple email from Visual C++ with gmail account");

    // Set email body
    oSmtp->BodyText = _T("this is a test email sent from Visual C++ project with Gmail");

    // Gmail SMTP server address
    oSmtp->ServerAddr = _T("smtp.gmail.com");

    // If you want to use direct SSL 465 port, 
    // Please add this line, otherwise TLS will be used.
    // oSmtp->ServerPort = 465;

    // detect SSL/TLS automatically
    oSmtp->SSL_init();

    // Gmail user authentication should use your 
    // Gmail email address as the user name. 
    // For example: your email is "gmailid@gmail.com", then the user should be "gmailid@gmail.com"
    oSmtp->UserName = _T("somerandomemail@gmail.com");
    oSmtp->Password = _T("somepassword");

    _tprintf(_T("Start to send email via gmail account ...\r\n" ));

    if( oSmtp->SendMail() == 0 )
    {
        _tprintf( _T("email was sent successfully!\r\n"));
    }
    else
    {
        _tprintf( _T("failed to send email with the following error: %s\r\n"),
            (const TCHAR*)oSmtp->GetLastErrDescription());
    }

    if( oSmtp != NULL )
        oSmtp.Release();

    int x;
    cin>>x;

    return 0;
}

Why is there an error when i attempt to use string variables instead of " " ???

#include "stdafx.h"
#include <iostream>
#include "easendmailobj.tlh"
using namespace EASendMailObjLib;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    string email = "randomemail1@gmail.com": //string variables

    ::CoInitialize( NULL );

    IMailPtr oSmtp = NULL;
    oSmtp.CreateInstance( "EASendMailObj.Mail");
    oSmtp->LicenseCode = _T("TryIt");

    // Set your gmail email address
    oSmtp->FromAddr = _T(email); // string variable instead of "   " , error is here

    // Add recipient email address
    oSmtp->AddRecipientEx( _T("randomemail2s@hotmail.com"), 0 );

    // Set email subject
    oSmtp->Subject = _T("simple email from Visual C++ with gmail account");

    // Set email body
    oSmtp->BodyText = _T("this is a test email sent from Visual C++ project with Gmail");

    // Gmail SMTP server address
    oSmtp->ServerAddr = _T("smtp.gmail.com");

    // If you want to use direct SSL 465 port, 
    // Please add this line, otherwise TLS will be used.
    // oSmtp->ServerPort = 465;

    // detect SSL/TLS automatically
    oSmtp->SSL_init();

    // Gmail user authentication should use your 
    // Gmail email address as the user name. 
    // For example: your email is "gmailid@gmail.com", then the user should be "gmailid@gmail.com"
    oSmtp->UserName = _T("somerandomemail@gmail.com");
    oSmtp->Password = _T("somepassword");

    _tprintf(_T("Start to send email via gmail account ...\r\n" ));

    if( oSmtp->SendMail() == 0 )
    {
        _tprintf( _T("email was sent successfully!\r\n"));
    }
    else
    {
        _tprintf( _T("failed to send email with the following error: %s\r\n"),
            (const TCHAR*)oSmtp->GetLastErrDescription());
    }

    if( oSmtp != NULL )
        oSmtp.Release();

    int x;
    cin>>x;

    return 0;
}

I get the following error

Error C2065: 'Lemail' : undeclared identifier
M4N
  • 94,805
  • 45
  • 217
  • 260
Computernerd
  • 7,378
  • 18
  • 66
  • 95

5 Answers5

2

A string literal and a std::string are two completely different things. Usually when a function f expects a const char* you can pass to it a string literal or you can use the method c_str() of a string like so f(email.c_str()).

However the problem here is that _T is not a function. It is a macro and it simply appends a L as prefix to string literals. There is no way you can use it for std::string. You will need to use some functions for the conversion.

Alternatively define a macro that does the same as _T and decides to use wstring or string depending on if UNICODE is defined. Try to read through the code and what does _T do and you should understand what I mean.

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
1

It depends on whether UNICODE is defined.

If it is, use std::wstring instead of string. Also, remove the _T wrapping the string variable and add .c_str()

Petter
  • 37,121
  • 7
  • 47
  • 62
  • And for consistency, I'd say, do this by defining a `tstring` type (the definition of which depends on the `UNICODE` macro), and then use `tstring` without additional conditional code. –  Feb 07 '14 at 10:02
  • @hvd On the contrary, I'd recommend getting rid of all the `_T`, `t`... stuff, and explicitly using either `char` or `wchar_t`. The code you need will be different in either case anyway. – James Kanze Feb 07 '14 at 12:23
  • @JamesKanze That's a valid approach, but there are also valid reasons for keeping code compatible to build in either the misnamed ANSI mode or Unicode. The code wouldn't be all that different for the two cases. `tstring email = _T("randomemail1@gmail.com"); ... oSmtp->FromAddr = email.c_str();` should work just fine, assuming `IMailPtr` supports both compilation modes too. (If it doesn't, then you're right, then just use whatever type of string is needed by `IMailPtr`.) –  Feb 07 '14 at 13:07
  • @hvd But as soon as you do anything non-trivial, you need different code for each of the modes. – James Kanze Feb 07 '14 at 13:15
  • @JamesKanze Fair point, but a surprising amount of code doesn't need to do anything non-trivial, and the bits of code that do can often be tightly contained in functions so simple that they are easily maintainable even if they need to have two separate implementations. But my experience probably doesn't match yours. –  Feb 07 '14 at 13:26
1

If this is the standard Microsoft junk (more exactly, an experiment that failed—what they wanted to achieve is laudable, but what they actually ended up with is useless extra complexity), you're best off getting rid of it: the function is main (not _tmain), use char (or wchar_t, depending on what you want, but it must be char in the declaration of main) instead of _TCHAR, and forget about the _T.

As for the immediate problem, the _T is a macro that will only work on string literals; that's the way it was designed. If you use it on anything else, it may expand to something like Lemail, which of course won't be known.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • _'If this is the standard Microsoft junk'_ Yes, it's just another stupid, badly written windows macro :( ... – πάντα ῥεῖ Feb 07 '14 at 10:05
  • 1
    @πάνταῥεῖ I hesitated with that expression. To give Microsoft credit, they were trying to solve a difficult problem, or at least to make it easy for their users to solve it. Regretfully, what they came up with doesn't work. (I rather suspect, in fact, that there is no way to make this problem simple. Handling international text is incredibly difficult, and all of the various proposed solutions in the past also have serious problems.) – James Kanze Feb 07 '14 at 12:21
0

invalid usage of _T(); it is for string literals.

So that line should be;

oSmtp->FromAddr = email.c_str();

Semih Ozmen
  • 571
  • 5
  • 20
0

This is the definition of _T:

#if defined(_UNICODE)
#define _T(x) L ##x
#else
#define _T(x) x
#endif

So as you can see, it just appends L infront of anything passed inside it. So if you pass in a string, for example _T("HELLO WORLD") it would translate to L"HELLO WORLD" if _UNICODE is defined.

Similarly if you pass in any other token, _T(email) for example, it would convert it to Lemail which is why you are getting an error.

Work around would be to use std::wstring and std::string as:

#if defined(_UNICODE)
#define String std::wstring
#else
#define String std::string
#endif

and use String email instead.

Aniket Inge
  • 25,375
  • 5
  • 50
  • 78