VC++ Link problem: fatal error C1047, “Chilkat*.lib’ was created with an older compiler than other objects; rebuild old objects and libraries”

Regarding the following VC++ link problem:

“fatal error C1047: The object or library file 'c:\Chilkat\libs\x64\ChilkatRel_x64.lib' 
was created with an older compiler than other objects; rebuild old objects and libraries”

This can be resolved by building without the /LTCG flag turned on. Unfortunately, it is not possible to use the /LTCG flag if you are using the Chilkat libraries. Compiling and linking your C++ application without using the /LTCG flag should resolve the problem.

PercentDone callback counts as an AbortCheck

Question:

“I’ve got the Chilkat C++ libs linked with my project, and am using the HTTP classes successfully.
One thing is confusing me, though. I’ve derived a class from CkHttpProgress.h and overridden AbortCheck(…) to provide cancellation support. However, AbortCheck(…) never gets called. At first, I thought perhaps the HTTP retrieval was occurring too quickly, so I set the “HeartbeatMs” property to “1”, and it still never gets called.
I know the assignment of the callback class is working, because if I override PercentDone(…), it does indeed get called.
Is it possible that my use of the HTTP QuickGetStr(…) method does not support the AbortCheck(…) callback? I’m (successfully) reading a small XML file from a web server in close proximity to the client.”

Answer:
The PercentDone callback method also has an “abort” argument, so it may also be used to abort a method while in progress.  In cases where the PercentDone callback provides abort capability, it counts as an AbortCheck callback — to prevent too many callbacks from bombarding your application.
Therefore, if HeartbeatMs is set to 100ms, and a PercentDone callback is fired, then the timer for the next AbortCheck callback is reset.  The entire operation could be short enough such that all of the callbacks are PercentDone callbacks, and AbortCheck never gets called.  The AbortCheck callback would only be called when the elapsed time between 1% completion intervals exceeds the HeartbeatMs.

Scan/Replace Text in Email Body in C++

This example may help C++ programmers needing to scan email bodies for strings and automatically replace:

void EmailBodyExample(void)
    {
    CkEmail email;

    // Set the plain-text and HTML alternative bodies.
    // Note: Because we're using literal strings, the strings passed
    // to these methods are ANSI strings (i.e. they are 1-byte per char
    // in this case).
    email.AddPlainTextAlternativeBody("á, é, í, ó, ú, abc");
    email.AddHtmlAlternativeBody("<html><body><p>á, é, í, ó, ú, abc</p></body></html>");

    // Suppose we don't know the language or charset of the email?
    // Maybe it's Chinese, perhaps it's Hebrew...
    // You can get the body text in utf-8 (the multibyte encoding of Unicode)
    // for all languages.  Here's how to do it:
    CkString strPlainTextBody;
    CkString strHtmlBody;

    // Get the email bodies into the CkString objects:
    email.GetPlainTextBody(strPlainTextBody);
    email.GetHtmlBody(strHtmlBody);

    // Now get the utf-8 (null-terminated) strings:
    const char *strUtf8PlainTextBody = strPlainTextBody.getUtf8();
    const char *strUtf8HtmlBody = strHtmlBody.getUtf8();

    // Suppose you want to modify the body and replace it?
    // Let's replace "abc" with "123".
    // One way to do it is like this:
    strPlainTextBody.replaceAllOccurances("abc","123");

    // Tell the email object that "const char *" arguments will point to utf-8,
    // not ANSI:
    email.put_Utf8(true);

    // Pass the modified utf-8 string.
    // AddPlainTextAlternativeBody will replace the existing plain-text
    // body if it already exists.
    email.AddPlainTextAlternativeBody(strPlainTextBody.getUtf8());

    // Another way to do it:
    char *tmpBuf = new char[strHtmlBody.getSizeUtf8()+1];   // Add 1 for the terminating null
    strcpy(tmpBuf,strUtf8HtmlBody);
    char *abc = strstr(tmpBuf,"abc");
    if (abc)
	{
	*abc = '1'; abc++;
	*abc = '2'; abc++;
	*abc = '3';
	}
    email.AddHtmlAlternativeBody(tmpBuf);

    delete [] tmpBuf;

    // Save the email and examine it using a text editor or email client..
    email.SaveEml("out.eml");
    }

Non-English String Literals in C++ Source Code

When a C++ compiler compiles a C++ source file, it must process the bytes according to a character encoding and that is typically ANSI.  ANSI is not a character encoding, it is simply a keyword that says “Use the default multi-byte character encoding for this computer based on its current locale.”   Therefore, if your program is originally written in Poland and contains string literals (i.e. character string constants in double-quotes) with Polish characters, the same source when compiled on a typical computer in France will not produce the same results.  The bytes for the Polish characters will instead be interpreted as Latin1 characters and the string will be different.  This example demonstrates a technique you may use to embed string literals using quoted-printable so that the C++ source may be compiled on any computer without character encoding issues caused by the locale.   Chilkat provides a free tool to quoted-printable encode a string (which may contain characters in any language):

Quoted-Printable Encoding Tool Download

Here is a screenshot:

Quoted-Printable Encoder

The quoted-printable encoder is a very simple C# program that uses the Chilkat.CkString class.   Here is the complete source code:

        private void button1_Click(object sender, EventArgs e)
        {
            Chilkat.CkString str = new Chilkat.CkString();
            str.append(textBox1.Text);
            str.qpEncode(comboBox1.Text);
            textBox2.Text = str.getString();
        }

Using Quoted-Printable String Literals in C++

Use the tool to convert your string to quoted-printable using the utf-8 character encoding.  (utf-8 is the multi-byte encoding for Unicode, so it is able to mix characters of any language in a single NULL-terminated string.  A “multibyte” encoding is a character encoding such that each character is represented by one or more bytes, and there are no NULL bytes.)

Use the quoted-printable encoded string in your C++ source code like this:
(This example constructs an IMAP mailbox name using Vietnamese characters)

    CkImap imap;
    bool success;
...

    CkString str;
    str.append("C=C3=B4ng c=E1=BB=99ng");
    str.qpDecode("utf-8");
    str.prepend("Inbox.");

    imap.put_Utf8(true);
    success = imap.CreateMailbox(str.getUtf8());
    if (success != true) {
        printf("%s\n",imap.lastErrorText());
        return;
    }

Utf8 C++ property allows for utf-8 or ANSI “const char *”

All Chilkat C++ classes have a Utf8 property. For example:

class CkEmail : public CkObject
{
    public:

	CkEmail();
	virtual ~CkEmail();

...
	bool get_Utf8(void) const;
	void put_Utf8(bool b);

...
	const char *addFileAttachment(const char *fileName);
...
};

The Utf8 property controls how the bytes pointed by “const char *” arguments are interpreted. By default, “const char *” strings are interpreted as ANSI bytes. If the Utf8 property is set to true by calling put_Utf8(true), then “const char *” inputs are interpreted as utf-8. This allows any application to pass either ANSI or utf-8 strings to any Chilkat method.

The Utf8 property also controls whether utf-8 or ANSI strings are returned by methods that return a “const char *”.

Chilkat C++ Libraries safe for multi-threading?

Question:
Are the Chilkat C++ libraries safe for multi-threading?

Answer:
Yes. However, it is best practice that you don’t allow multiple threads to call methods on the same object instance at the same time.

Also, objects that communicate via an Internet protocol, such as SMTP, POP3, IMAP, FTP, HTTP, etc. should not be shared between threads. It is OK to have separate instances of a MailMan object (for example) that each has it’s own POP3 and/or SMTP session. But it doesn’t make sense for multiple threads to be trying to share the same POP3/SMTP/FTP/HTTP/IMAP/… session. The reason is that these protocols are stateful and not designed for “multiple conversations” to be occuring simultaneously w/ multiple clients in a single TCP/IP connected session.