Tutorial: How to Use Dynamsoft SAWS COM SDK in C++
Abstract: The Dynamsoft SourceAnywhere Standalone COM Software Development Kit (SDK) enables us to integrate Dynamsoft SourceAnywhere Standalone functionality with your Windows application that is written in a language which supports Microsoft’s Component Object Model. More specifically, here in this article, we will describe how to integrate the Dynamsoft SourceAnywhere Standalone functionality into our C++ programs. Introduction: Microsoft COM (Component Object Model) technology enables software components to communicate from the binary code level. And COM objects can be created with a variety of programming languages such as VB, C# and C++. While in the official SAWSSDK help document, only VB examples are provided which helps to simplify things, other people may want to integrate the Dynamsoft SourceAnywhere Standalone functionality into their C++ programs. There things could be more complicated. In this article we provide a step by step example of using a C++ program to get all the repository information from the SAW server and will explain the basic knowledge around using the SAWS SDK from C++. Also, we will give general instructions on how to code up the C++ programs via translating the code from the VB examples in the official help documentation. Step by Step Approach: In this section, we will implement a simple customized MFC SAWS client to get the information of all repository names from the SAWS Server. You have to install the SAWS Server and SDK in order to prepare the environment. We will use Visual Studio 2012 as the IDE. (1) In VS 2012, create a new dialog based MFC project with default settings and make the dialog GUI looks like the following Figure 1.
Figure 1
(2) Just below the last line of #include “afxdialogex.h” add the following code as Snippet 1 indicates. #import “C:\Program Files (x86)\Dynamsoft\SourceAnywhere SDK\SAWSSDK.dll” [csharp]#include “stdafx.h” #include “DynamsoftSAWSDKDemo.h” #include “DynamsoftSAWSDKDemoDlg.h” #include “afxdialogex.h” #import “C:\Program Files (x86)\Dynamsoft\SourceAnywhere SDK\SAWSSDK.dll”[/csharp]
Snippet 1
This is the usual way to load COM library. And it will import/load the COM library in the .dll file specified in the import path into our program so that we can use all the objects and methods provided by the COM SDK. (3) Add the click event for the Login button and we then need to code up the logic step by step to show all the repository names from the server. In C++, different from VB, the first step is to initialize the COM library (line 161 in Snippet 2), and we need to create an instance for our core SDK object SAWSAppObject which exposes all the methods we need to interact with the server (e.g., receive data and send data) . [csharp]::CoInitialize(NULL); // the core interface provided by the SDK SAWSSDKLib::ISAWSAppObjectPtr pSAWSAppObj; pSAWSAppObj.CreateInstance(__uuidof(SAWSSDKLib::SAWSAppObject));[/csharp]
**Snippet 2**
Remarks: The official help document of the SAWS SDK only provides VB samples which simplify things. While in C++, we usually use smart pointer, IXXXPtr where XXX (e.g., SAWSAppObject, line 165 in Figure 3) refers to the full object name in the official document. More specifically, if you encounter a name like SAWSSDKLib.SAWSAppObject in the help document, you might want to convert this name as SAWSSDKLib::ISAWSAppObjectPtr in C++. (4) Next we prepare some login information to connect and login to the server, and to simplify stuff, we edit the following information in the code, as Snippet 3 indicates: [csharp]// prepare the login info BSTR bstrServerIP = L”127.0.0.1”; long lServerPort = 7777; BSTR bstrUserName = L”admin”; BSTR bstrPassword = L”1”; BSTR bstrDBServerName; BSTR bstrDBName; VARIANT_BOOL bCancelled; // for [out] BSTR bstrResultDescription; // for [out][/csharp]
Snippet 3
(5) In order to get all repository names, we need three methods from the SAWS COM SDK. We can check the methods: ConnectToServer, Login, GetAllRepositories. That is, we first need to connect to the server and then login into the server so we can be authorized to communicate with the server (receive and send data). After successfully connecting and loging into the server we can finally get the repository information by calling the third method GetAllRepositories as listed. Basically, we can write the C++ code quite the same way as the VB sample shows in the official SAWSSDK document. There are several general instructions on how to translate the VB code in the document into C++: First, we need to add ‘SAWSSDKLib::’ this namespace before each object type. Second, for the parameters in the methods we need to use exactly the same list in the method declaration from the document. VB simplifies things a lot and thus will do type conversion by itself. However in C++ we need to make sure the type matches exactly. We can check Snippet 4 and 5 for reference. [csharp] // long connectToServer() { SAWSSDKLib::Enum_EncryptType enumEncryptType; VARIANT_BOOL bOnlyTrial; long lLeftTrialDays; VARIANT_BOOL bRealServer; long lRet = pSAWSAppObj->ConnectToServer( bstrServerIP, lServerPort, SAWSSDKLib::Enum_NOPROXY, “”, 0, “”, “”, FALSE, “”, &enumEncryptType, &bOnlyTrial, &lLeftTrialDays, &bRealServer, &bstrDBServerName, &bstrDBName, &bCancelled, &bstrResultDescription); if(lRet) { ::AfxMessageBox(_T(“Failed to connect to server. Details: “) + CString(bstrResultDescription)); return ; } }[/csharp]
**Snippet 4**
[csharp] // long login() { long lDaysOfExpiration; VARIANT_BOOL bMustChangePassword; SAWSSDKLib::ISAWSKeyFileSetPtr pKeyFileSet; pKeyFileSet.CreateInstance(__uuidof(SAWSSDKLib::SAWSKeyFileSet)); long lRet = pSAWSAppObj->Login( bstrUserName, bstrPassword, bstrDBName, “Default”, pKeyFileSet, &bMustChangePassword, &lDaysOfExpiration, &bCancelled, &bstrResultDescription); if(lRet) { ::AfxMessageBox(_T(“Failed to Login. Details: “) + CString(bstrResultDescription)); return ; } }[/csharp]
Snippet 5
Remarks: Don’t try to use BOOL or bool to replace VARIANT_BOOL, they are different types and the conversion between them could cause errors. . (6) After successfully connecting and loging into the server, we can utilize the third method to retrieve the repository names (Snippet 6). [csharp] // displayRepositories { SAWSSDKLib::ISAWSRepositoryInfoSetPtr pRepositoryInfoSet; pRepositoryInfoSet.CreateInstance(__uuidof(SAWSSDKLib::SAWSRepositoryInfoSet)); long lRet = pSAWSAppObj->GetAllRepositories( &pRepositoryInfoSet, &bCancelled, &bstrResultDescription); if(lRet) { ::AfxMessageBox(_T(“Failed to get repository info. Details: “) + CString(bstrResultDescription)); return ; } long lLength = pRepositoryInfoSet->GetCount(); for(long i = 0; i < lLength; ++i) { SAWSSDKLib::ISAWSRepositoryInfoPtr pRepositoryInfo; pRepositoryInfo = pRepositoryInfoSet->Item(i); // m_listOutput.InsertString(i, pRepositoryInfo->GetRepositoryName()); } } ::CoUninitialize();[/csharp]
**Snippet 6**
(7) We then click the Logi: button, the following is the expected result:
Figure 2
Conclusion: This article introduces how to integrate Dynamsoft SourceAnywhere Standalone functionality into our C++ programs. The general instruction is that we can read the official SAWS SDK document to learn what objects and methods we can use. Then we can read the VB sample code and prepare the objects and data to pass into the methods in the same manner as our C++ sample here. Remember the differences between VB and C++ as pointed out here and we will know how to call other methods and accomplish more complicated tasks like adding files, checking in and so on.