Show in Frame No Frame
Up Previous Next Title Page Index Contents Search

9.2.4 API with C/C++

This section explains how to use the API from C/C++ using the free gSOAP library. As with C# and Java, a working knowledge of C/C++ programming is expected from the reader. The instructions and ancillary files mentioned below are for the latest version of gSOAP at the time of writing. Some details may change with newer versions, so for first time use it is recommended to start with exactly the version specified below.

Download the 2.8.18 version of gSOAP from https://sourceforge.net/projects/gsoap2 (if the aforementioned version is no longer available from gSOAP Toolkit project’s home page you can locate it by selecting Files tab and browsing the list of old versions). Once you have completed the download, extract the .zip file into a folder C:\gsoap-2.8 (if you have no privileges to write onto drive C:, choose another location you have the rights to write to).

Start MetaEdit+, open the API Tool by selecting API Tool from the Main Launcher’s toolbar and create the required WSDL file by pressing the Save WSDL button. Save or copy the MetaEdit.wsdl file into C:\gsoap-2.8\gsoap\bin\win32. Open the Command Prompt, change to that folder and execute the following two commands:
wsdl2h -c MetaEdit.wsdl
soapcpp2 -C MetaEdit.h
As a result you should get the following files in this directory:
*soapC.c
*soapClient.c
*soapH.h
*soapStub.h
*MetaEditAPISoapBinding.nsmap
Copy these files to your own directory for C programs (there are also some other generated files but you don’t need them, so you can either leave them there or delete them). In addition to these generated files, also copy the generic gSOAP library files stdsoap2.h and stdsoap2.c (and stdsoap2.cpp if you are using C++) from C:\gsoap-2.8\gsoap into your own directory.

With the required libraries and definitions in place, the next step is to provide our own SOAP client code. Listing 4 shows an example code for application that highlights an Object in MetaEdit+ using gSOAP with C:
01 #include "stdlib.h"
02 #include "string.h"
03 #include "soapH.h"
04 #include "MetaEditAPISoapBinding.nsmap" 
05
06 int main()
07 {
08   struct soap meServer;
09
10   struct ns2__METype graphType;
11   struct ns1__allGoodInstancesResponse allGoodInstancesResponse;
12   struct MEOopArray *resultPtr;
13   struct ns2__MEOop graph;
14   struct ns2__METype objectType;
15   struct ns2__MEAny *props[1];
16   struct MEAnyArray propArray;
17   struct ns2__MEAny *values[1];
18   struct MEAnyArray valueArray;
19   struct ns2__MEAny area, np;
20   struct ns1__instPropsResponse instPropsResponse;
21   struct ns2__MEAny newObjectAny;
22   struct ns2__MEOop newObject;
23   struct ns1__addToGraphResponse addToGraphResponse;
24   struct ns1__diagramsResponse diagramsResponse;
25   struct ns2__MEOop diagram;
26   struct ns2__MEAny place;
27   struct ns1__addNewObjectRepForResponse addNewObjectRepForResponse;
28   struct ns2__MEAny nullAny;
29   struct ns2__MEAny textAny;
30   struct ns1__animateResponse animateResponse;
31   char *token, *next_token;
32
33   soap_init1(&meServer, SOAP_IO_KEEPALIVE); 
34 
35   graphType.name = "WatchFamily";
36   if(soap_call_ns1__allGoodInstances(&meServer, NULL, NULL, &graphType,
37      &allGoodInstancesResponse) != SOAP_OK) {
38      soap_print_fault(&meServer, stderr);
39      exit(1);
40   }
41   resultPtr = allGoodInstancesResponse.result;
42   if (!resultPtr->__size) exit(2); /* No WatchFamily graphs found */
43   graph = **resultPtr->__ptr;
44   objectType.name = "Note [Watch]";
45   nullAny.meType = "MENull";
46   nullAny.meValue = "";
47   props[0] = &nullAny;
48   propArray.__ptr = &props[0];
49   propArray.__size = 1;
50   textAny.meType = "Text";
51   textAny.meValue = "'A new note created by the API'";
52   values[0] = &textAny;
53   valueArray.__ptr = &values[0];
54   valueArray.__size = 1;
55   np = area = nullAny;
56   if(soap_call_ns1__instProps(&meServer, NULL, NULL, &objectType, &propArray,
57      &valueArray, &np, &area, &instPropsResponse) != SOAP_OK) {
58      soap_print_fault(&meServer, stderr);
59      exit(1);
60   }
61   newObjectAny = *instPropsResponse.result;
62   if (strcmp(newObjectAny.meType, "MEOop")) exit(3); /* Object not created */
63   token = strtok_s(newObjectAny.meValue, "_", &next_token);
64   newObject.areaID = atoi(token);
65   token = strtok_s(NULL, "", &next_token);
66   newObject.objectID = atoi(token);
67   if(soap_call_ns1__addToGraph(&meServer, NULL, NULL, &newObject, &graph,
68      &addToGraphResponse) != SOAP_OK) {
69      soap_print_fault(&meServer, stderr);
70      exit(1);
71   }
72   if(soap_call_ns1__diagrams(&meServer, NULL, NULL, &graph, &diagramsResponse)
73      != SOAP_OK) {
74      soap_print_fault(&meServer, stderr);
75      exit(1);
76   }
77   resultPtr = diagramsResponse.result;
78   if (!resultPtr->__size) exit(4); /* No existing diagrams found */
79   diagram = **resultPtr->__ptr;
80   place.meType = "Point";
81   place.meValue = "400,360";
82   if(soap_call_ns1__addNewObjectRepFor(&meServer, NULL, NULL, &diagram, &newObject,
83      0, &place, &addNewObjectRepForResponse) != SOAP_OK ) {
84      soap_print_fault(&meServer, stderr);
85      exit(1);
86   }
87   if (soap_call_ns1__animate(&meServer, NULL, NULL, &graph, &newObject,
88       &animateResponse) != SOAP_OK) {
89       soap_print_fault(&meServer, stderr);
90       exit(1);
91   }
92  
93   soap_end(&meServer); 
94   soap_done(&meServer); 
95   return 0;
96 }

Listing 4. Sample C application using the API.

The general explanation of what the client is doing is provided in Section 9.2.1. As for this C implementation, follow the code from line 33 onwards. Line 33 initializes the SOAP connection to MetaEdit+ API Server, with the SOAP_IO_KEEPALIVE flag to make the connection be reused rather than closed and opened again for each command. Lines 35–43 take care of the example steps 1 and 2 by finding all possible WatchFamily graphs. Lines 44–61 create the new object (steps 3 to 7) and lines 62–71 add the new object into the ‘WatchModels’ graph (steps 8 and 9). Finally, lines 72–86 add the representation for the new object (steps 10 and 11) and lines 87-91 take care of the highlighting the new object. Lines 93–94 then quit the SOAP connection.

To test your program, start MetaEdit+, login and open the Digital Watch project, make sure the ‘WatchModels’ WatchFamily diagram is closed, open the MetaEdit+ API tool and press the Start Server button. Compile your code along with the additional gSOAP libraries and files and run the resulting program. Go back to MetaEdit+ and you should see the ‘WatchModels’ diagram open with the new Note object highlighted (as in Figure 9–2).

Show in Frame No Frame
Up Previous Next Title Page Index Contents Search