April 13, 2012

Linking “C” Programs with the Chilkat C/C++ Libs

Filed under: C language, Linking — Tags: , — admin @ 7:26 am

The Chilkat C/C++ libs are (internally) written in C++.  Therefore, when linking a “C” program with the Chilkat libs, the C++ runtime libs must be included.  This is true regardless of the operating system, whether it be Windows, MAC OS X, IOS, Linux, etc.    Different build environments will have different ways of accomplishing the task.  For example, with XCode (on Mac OS X), simply adding an empty source file having a filename with the extension “.cpp” is all that is needed.  This blog post will show how to link a “C” program on Linux with the Chilkat C/C++ static library.  The solution is to use “g++” for the link phase instead of “gcc”.  The telltale indicator that the C++ runtime libs are missing is when you see errors involving “__cxxabiv1″, such as the following:

undefined reference to `vtable for __cxxabiv1::__class_type_info'

Here is a simple C program with a simple shell script to build it correctly.

buildTest.sh (This is for 64-bit Linux. Notice that g++ is used for linking, not gcc.)

#!/bin/bash -ev

gcc -m64 -Werror -c -fmessage-length=0 -fno-stack-protector -fPIC -o"cTest.o" "cTest.c"

g++ -g0 -m64 -L"/home/chilkat/workspace/chilkat/lib64_static" ./cTest.o -o"cTest"
    -lchilkat-9.3.0 -lpthread -lresolv

cTest.c

#include <stdio.h>
#include "../chilkat/include/C_CkFtp2.h"

void testFtp2Create(void)
    {
    HCkFtp2 ftp;
    BOOL success;

    ftp = CkFtp2_Create();

    //  Any string unlocks the component for the 1st 30-days.
    success = CkFtp2_UnlockComponent(ftp,"Anything for 30-day trial");
    if (success != TRUE) {
        printf("%s\n",CkFtp2_lastErrorText(ftp));
    }

    CkFtp2_Dispose(ftp);
    }

int main(int argc, char *argv[])
{
	testFtp2Create();
	printf(”Hello World!\n”);
	return 0;
}

March 15, 2012

(C++) Return Email Headers as iso-8859-15? (or any other charset)

Filed under: charset, cpp — Tags: , , — admin @ 2:58 pm

Question:

In C++, is it somehow possible to specify a desired charset (like ISO-8859-15) when getting mail headers with POP3?

Answer:

Instead of calling the method that returns a “const char *” — which can return either utf-8 or ANSI (see this Chilkat blog post about the Utf8 property common to all Chilkat C++ classes), call the alternate method that returns the string in a CkString object.  You can then get the iso-8859-15 string from the CkString object.

Each Chilkat C++ method that returns a string has two versions — an upper-case version that returns the string in a CkString (always the last argument), and a lower-case version that returns a “const char *”.

For example, in the CkEmail class:

bool GetHeaderField(const char *fieldName, CkString &outFieldValue);
const char *getHeaderField(const char *fieldName);

The lower-case method returning a “const char *” returns a pointer to memory that may be overwritten in subsequent calls.  Therefore, make sure to copy the string to a safe place immediately before making additional calls on the same Chilkat object instance.  (Only methods that also return “const char *” would overwrite the memory from a previous call.)

The upper-case version of the method returns the string in a CkString object.  It is an output-only argument, meaning that the CkString contents are replaced, not appended.  To get the iso-8859-15 string from the CkString, call the getEnc method.  For example:

const char  *str_iso_8859_15 = outFieldValue.getEnc("iso-8859-15");

This returns a NULL-terminated string where each character is represented as a single byte using the iso-8859-15 encoding.

January 21, 2011

Chilkat C/C++ libraries now available for MAC OS X

Filed under: MAC OS X — Tags: , — admin @ 5:56 am

The Chilkat C/C++ libraries are now available for MAC OS X. For the download link and more information, see http://www.chilkatsoft.com/installMacOSX.asp

Chilkat will soon release MAC OS X compatible builds for Java, Perl, Python, and Ruby. Following that, builds for the IOS (IPhone) will be released, along with Objective-C/C++ native libraries for both MAC OS X and IPhone.

December 14, 2009

Very simple C# SSH Shell Console Terminal

Filed under: SSH — Tags: , , , , — admin @ 2:48 pm

Here’s an example that demonstrates a rough start to creating a C# console SSH shell terminal (where the user can type commands and output from the remote command echos to the console:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace SshTerminalConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            Chilkat.Ssh ssh = new Chilkat.Ssh();
            ssh.UnlockComponent(”Test”);

            //  Hostname may be an IP address or hostname:
            string hostname = “192.168.1.117″;
            int port = 22;

            Console.WriteLine(”Connecting…”);

            //ssh.KeepSessionLog = true;
            bool success = ssh.Connect(hostname, port);
            if (success != true)
            {
                Console.WriteLine(ssh.LastErrorText + “\r\n”);
                // Read so we can see the error before the console closes.
                string x = Console.ReadLine();
                return;
            }

            //  When reading, if no additional data arrives for more than
            //  5 seconds, then abort:
            ssh.IdleTimeoutMs = 5000;

            Console.WriteLine(”Authenticating…”);

            //  SSH Server Authentication
            //  If there is no login/password required, you must still call
            //  AuthenticatePw and use any values for login/password.
            success = ssh.AuthenticatePw(”chilkat”, “***”);
            if (success != true)
            {
                Console.WriteLine(ssh.LastErrorText + “\r\n”);
                // Read so we can see the error before the console closes.
                string x = Console.ReadLine();
                return;
            }

            Console.WriteLine(”Opening Channel…”);

            //  Open a session channel.
            int channelNum = ssh.OpenSessionChannel();
            if (channelNum < 0)
            {
                Console.WriteLine(ssh.LastErrorText + “\r\n”);
                // Read so we can see the error before the console closes.
                string x = Console.ReadLine();
                return;
            }

            //  Request a pseudo-terminal
            string termType;
            termType = “dumb”;
            int widthInChars;
            widthInChars = 120;
            int heightInChars;
            heightInChars = 40;
            int pixWidth;
            pixWidth = 0;
            int pixHeight;
            pixHeight = 0;
            success = ssh.SendReqPty(channelNum, termType, widthInChars, heightInChars, pixWidth, pixHeight);
            if (success != true)
            {
                Console.WriteLine(ssh.LastErrorText + “\r\n”);
                // Read so we can see the error before the console closes.
                string x = Console.ReadLine();
                return;
            }

            Console.WriteLine(”Starting a shell…”);

            //  Start a shell on the channel:
            success = ssh.SendReqShell(channelNum);
            if (success != true)
            {
                Console.WriteLine(ssh.LastErrorText + “\r\n”);
                // Read so we can see the error before the console closes.
                string x = Console.ReadLine();
                return;
            }

            // Loop to read from the SSH channel, output to the console, and read keyboard input from the console.
            StringBuilder sb = new StringBuilder();
            while (true)
            {
                if (Console.KeyAvailable)
                {
                    ConsoleKeyInfo key = Console.ReadKey(true);
                    Console.Write(key.KeyChar);

                    switch (key.Key)
                    {
                        case ConsoleKey.Enter:
                            Console.WriteLine(”");

                            sb.Append(”\n”);
                            success = ssh.ChannelSendString(channelNum, sb.ToString(), “ansi”);
                            if (success != true)
                            {
                                Console.WriteLine(ssh.LastErrorText + “\r\n”);
                                // Read so we can see the error before the console closes.
                                string x = Console.ReadLine();
                                return;
                            }

                            sb.Length = 0;
                            break;
                        default:
                            //Console.Write(key.KeyChar);
                            sb.Append(key.KeyChar);
                            break;
                    }

                }

                // Now check for incoming data from the SSH channel.
                int retval = ssh.ChannelPoll(channelNum, 10);
                if (retval == -1)
                {
                    Console.Write(ssh.LastErrorText);
                    Console.WriteLine(”");
                    // Read so we can see the error before the console closes.
                    string x = Console.ReadLine();
                    return;
                }
                if (retval > 0)
                {
                    Console.Write(ssh.GetReceivedText(channelNum, “ansi”));
                }
                else
                {
                    // If data arrived, loop around and get more immediately.
                    // Otherwise wait 20ms.
                    System.Threading.Thread.Sleep(20);
                }

            }  

        }
    }
}

December 4, 2009

Aborting in C++

Filed under: events — Tags: , , — admin @ 3:32 pm

The technique for aborting any time-consuming Chilkat C++ method call follows this recipe:

  1. Declare your own class that derives from the appropriate Chilkat progress monitoring class.  For CkMailMan it is CkMailProgress (as shown below).  For other Chilkat classes it is CkHttpProgress, CkFtpProgress, CkImapProgress, CkZipProgress, etc.
  2. Create an implementation for the AbortCheck method.  This will override the default implementation from the base class.  (The default implementation simply does nothing.)
  3. The AbortCheck method is called periodically according to the value of the HeartbeatMs property.  The default value of HeartbeatMs is 0, which indicate that no AbortCheck events should be called.  Set HeartbeatMs to a non-zero value (in milliseconds) to enable the AbortCheck callbacks.  Do this by calling put_HeartbeatMs(someValue)  as shown below.
  4. Whenever your application wishes to abort an operation in progress (SMTP, POP3, IMAP, Zip, FTP, etc.), set the abort boolean argument of AbortCheck to true.
  5. Don’t forget to hookup your event monitoring class by calling the SetProgressCallback method.  (See the code example below.)  In some classes, such as for CkImap, the way to hookup the event class is via the put_EventCallbackObject function.  Please review the .h file for details.
#include <CkMailProgress.h>

class MyMailProgress : public CkMailProgress
    {
    public:
	MyMailProgress(void) { }
	virtual ~MyMailProgress(void) { }

	// Override the AbortCheck method (which is a virtual method in CkMailProgress)
	// Called periodically according to the value of the HeartbeatMs property.
	void AbortCheck(bool *abort)
	    {
	    printf("AbortCheck!\n");

	    // If your application wishes to abort the email sending/receiving operation,
	    // set the abort boolean like this:
	    *abort = true;
	    }

        // Percentage completion events may also be overridden to abort time-consuming operations.
	void SendPercentDone(long pctDone, bool *abort)
	    {
	    printf("SendPercentDone: %d percent\n",pctDone);
	    }
	void ReadPercentDone(long pctDone, bool *abort)
	    {
	    printf("ReadPercentDone: %d percent\n",pctDone);
	    }

    };

void AbortCheckDemo(void)
    {
    CkMailMan mailman;
    bool success;
    success = mailman.UnlockComponent("30-day trial");
    if (success != true)
	{
        printf("%s\n",mailman.lastErrorText());
        return;
	}

    // Set the HeartbeatMs property so that AbortCheck is called once every 80 milliseconds.
    mailman.put_HeartbeatMs(80);

    MyMailProgress myProgress;
    mailman.SetProgressCallback(&myProgress);

    CkEmail email;
    // ...
    // ...

    // The AbortCheck event is called periodically while SendEmail is in progress..
    // (Note: In some cases, including here, a percent-done event is also called, and it will have an "abort"
    // boolean argument that may be set to "true" to force an abort.
    // If the percent-done callbacks happen more frequently than the HeartbeatMs setting, then
    // the AbortCheck events may not be fired at all.)
    success = mailman.SendEmail(email);
    if (success != true)
	{
        printf("%s\n",mailman.lastErrorText());
        return;
	}

    }

October 30, 2009

Socket SendString (C++) w/ TCHAR

Filed under: TCHAR — Tags: , , — admin @ 5:28 am

Question:

I need to send a unicode string (e.g TCHAR *ptr) but the API only allows to send char.

Answer:

/*
The _TCHAR data type is defined conditionally in Tchar.h.
If the symbol _UNICODE is defined for your build, _TCHAR is defined as wchar_t;
otherwise, for single-byte and MBCS builds, it is defined as char.
*/
bool sendString(CkSocket &sock, TCHAR *str)
    {
    bool success = false;

#ifdef _UNICODE
    success = sock.SendBytes((const unsigned char *)str, _tcslen(str) * 2);
#else
    success = sock.SendString(str);
#endif

    return success;
    }

October 2, 2009

Is Calling .Dispose() Recommended for C# and VB.NET?

Filed under: C#, Dispose, VB.NET — Tags: , , , — admin @ 6:39 am

Question:

In your examples online, we have noticed that .Dispose() is never
called after using Chilkat classes (we are writing in C#).

Is calling .Dispose() recommended?  Does your code not need to destroy
any native resources or handles that would normally be cleaned up in
the Dispose method (the IDisposeable interface) ?

Answer:

For objects that manage a TCP/IP socket connection with a server (FTP2, SSH, SFTP, POP3, SMTP, IMAP, HTTP, etc.) then calling Dispose will close the connection.  Aside from memory-usage and socket connections, there are no other resources used by Chilkat classes.  Dispose may also deallocate some internal memory.

The important thing to realize is that once Dispose is called, your code should not use that particular instance of the object again.  I always prefer a more explicit approach.  For example, instead of calling Chilkat.MailMan.Dispose to ensure that a connection to the SMTP server is closed, call Chilkat.MailMan.CloseSmtpConnection.  (If the mailman is not actually connected, calling CloseSmtpConnection does NOT result in an error.  It is harmless.)

Also, when an Chilkat object’s finalizer is called (i.e. when it is garbage-collected), any existing socket connections are closed and internal memory is (of course) deallocated.   You may force garbage collection by doing this (in C#)

 GC.Collect();
 GC.WaitForPendingFinalizers();

September 16, 2009

Chilkat C++ Libs - Link and Maintain Single EXE?

Filed under: Linking — Tags: , — admin @ 7:14 am

Question:

I am developing a single EXE in C++ that doesn’t make use of any external libraries and including MFC. Can I add your zip libaries to my application and still maintain the application as a single EXE?

Answer:

Yes, the Chilkat C++ libs may be linked directly into your application.  This results in a single EXE containing the Chilkat library code required to satisfy all direct and indirect references.  (The linker includes only the code needed to resolve all references.)  You may run your EXE on any computer because the licensing is royalty-free.  Internally, Chilkat does not use or reference MFC.   (Note: MFC applications may still use the Chilkat libs.  The point is this: if your application does not use MFC, then linking with Chilkat will not cause MFC to be “pulled-into” your EXE.)

September 14, 2009

HTTP Progress Monitoring in C++

Filed under: HTTP, events — Tags: , , , , — admin @ 7:20 am

This blog post shows how to monitor the progress of HTTP uploads and downloads in C++.  The first step is to create a C++ callback class that derives from the CkHttpProgress base class.  You’ll be overriding one or more of the callback methods.  For example:

class MyHttpProgress : public CkHttpProgress
    {
    public:
	MyHttpProgress(void) { }
	virtual ~MyHttpProgress(void) { }

	void PercentDone(int pctDone, bool *abort)
	    {
	    printf("PercentDone: %d percent\n",pctDone);

	    // To abort the HTTP operation, set the abort flag equal to true.
	    //if (pctDone > 10)
		//{
		//*abort = true;
		//}
	    }
	void AbortCheck(bool *abort)
	    {
	    // To abort the HTTP operation, set the abort flag equal to true.
            // Like this:
            // *abort = true;

            // Note: The AbortCheck event callback is called periodically according to the HeartbeatMs
            // property setting.

	    printf("AbortCheck!\n");
	    }
	void HttpBeginReceive(void) { printf("HttpBeginReceive!\n"); }
	void HttpEndReceive(bool success) { printf("HttpEndReceive!\n"); }
	void HttpBeginSend(void) { printf("HttpBeginSend!\n"); }
	void HttpEndSend(bool success) { printf("HttpEndSend!\n"); }

    };

In your C++ application, create an instance of your MyHttpProgress class and tell the CkHttp object to use it by calling put_EventCallbackObject. Here’s an example:

void TestDownloadWithEventCallbacks(void)
    {
    MyHttpProgress eventObj;

    CkHttp http;
    bool success = http.UnlockComponent("Anything for 30-day trial");

    http.put_EventCallbackObject(&eventObj);

    success = http.Download("http://www.chilkatsoft.com/something/something.zip","something.zip");
    if (!success)
        {
        printf("%s\n",http.lastErrorText());
        }
    else
        {
        printf("Finished.\n");
        }

    }

September 12, 2009

Scan/Replace Text in Email Body in C++

Filed under: VC++, email — Tags: , , — admin @ 6:37 am

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”);
    }
Newer Posts »