Create and consume custom C++ and COM components

This topic shows how to create and consume a custom Component Object Model (COM) component, and explains the reasons for writing a custom coarse-grained C++ and COM extension to ArcGIS Engine and ArcGIS Server (consumed from ArcGIS Engine and ArcGIS Server Java applications), how to use proxygen as a tool to generate Java proxies for the extension, and how to use the extension from an ArcGIS Engine Java application.

In this topic

About create and consume custom C++ and COM components

ArcGIS Java application programming interfaces (APIs) provide Java proxies for ArcObjects COM components, allowing ArcObjects to be accessed through Java. It can be useful to extend ArcObjects using custom COM components, and to programmatically access the extensions through Java. This can be useful in the following situations:

Write an ArcGIS Engine extension in C++ and COM

This topic demonstrates the writing of a custom coarse-grained COM component that performs the task of calculating the total area of all polygon features in a feature class. A Java application then uses the custom coarse-grained component to execute the task at the expense of just one method call, rather than performing several interop calls between Java and ArcObjects.

Write the extension

The following code example is essentially a COM component that implements one interface, which exposes the CalculateTotalArea method. The code example is located in the ARCGISHOME\java\samples\data\proxygen folder. A snippet of the .idl file is shown as follows:
import "oaidl.idl";
import "ocidl.idl";
[uuid(3760A0D0 - A56C - 4C19 - A3ED - 9D3DF225632D), version(1.0), helpstring(
    "ArcGISExtension 1.0 Type Library")] library ARCGISEXTENSIONLib{
    [object, uuid(B9CC08B8 - 98F4 - 4EBD - A267 - A0750BDE9A8E), 

    helpstring("IAGSExtension Interface"), pointer_default(unique)] interface
        IAGSExtension: IUnknown{
        [helpstring("method CalculateTotalArea")] HRESULT CalculateTotalArea([in]
            IFeatureClass * fc, [out, retval] double * result);
    [uuid(EE2820F3 - F9F1 - 4826-9C22 - 20CFC7D9950A), helpstring(
        "AGSExtension Class")] coclass AGSExtension{
        [default] interface IAGSExtension;
The .idl file imports the esriGeodatabase.olb type library to obtain the definition of the IFeatureClass interface that the CalculateTotalArea method receives as input. The definition of the method that performs the calculation of feature areas is described in the following code example:
STDMETHODIMP CAGSExtension: : CalculateTotalArea(IFeatureClass * pFeatureClass,
    double * result){
    esriGeometryType type;
    pFeatureClass -  > get_ShapeType(&type);
    if (type != esriGeometryPolygon)
        return 0;
    long numFeatures = 0;
    pFeatureClass -  > FeatureCount(NULL, &numFeatures);
    IFeature * pFeature = 0;
    IGeometry * pShape = 0;
    IArea * pArea = 0;
    for (int i = 0; i < numFeatures; i++){
        pFeatureClass -  > GetFeature(i, &pFeature);
        pFeature -  > get_Shape(&pShape);
        pShape -  > QueryInterface(&pArea);
        double area = 0;
        pArea -  > get_Area(&area);
         * result += area;
        pFeature -  > Release();
        pShape -  > Release();
        pArea -  > Release();
    return S_OK;
The preceding COM component was built using the Visual Studio 6 integrated development environment (IDE). The effort to port the project to later versions of the Visual Studio development environment should be minimal.

Generate Java proxies using proxygen

After writing and building the custom COM extension, generate Java proxies for the extension using proxygen. The type library information is used by proxygen, which is produced while building the custom COM component to generate Java proxies. As described in the proxygen tool instructions, proxygen needs to be supplied with a text file that contains information in the following format:
<COM type library location>, <java package name>, <java proxies’ location>
The text file used to generate proxies for the custom COM extension demonstrated in this topic, contains the following information:
C:\proxygen\ArcGISExtension\ArcGISExtension.tlb, agsextension,
Run the proxygen tool from the console, supplied with the text file. See the following screen shot:

If the Java proxies were generated successfully, a Success message displays.

Consume the extension from a Java application

Once Java proxies for the custom COM component are generated successfully, add the proxies to an existing Java ArcGIS Engine project within an IDE so the custom component can be consumed. The following Java code example shows how this is done:
// Initialize the engine and perform licensing.
AoInitialize ao = new AoInitialize();

// Open a shapefile workspace and obtain a feature class. 
IWorkspaceFactory shpFileWSFactory = new ShapefileWorkspaceFactory();
IFeatureWorkspace shpFileWS = (IFeatureWorkspace)shpFileWSFactory.openFromFile(
    "C:/Data/World", 0);
IFeatureClass featureClass = shpFileWS.openFeatureClass("Country");

// Consume the custom extension for calculating the total area of all features.
AGSExtension agsExtension = new AGSExtension();
double totalArea = agsExtension.calculateTotalArea(featureClass);
System.out.println("The total area of all features is " + totalArea);
The sample application calculated the total area of 3,140 polygon features representing all the counties in the United States. An 18 percent improvement in the running time resulted when the application used the custom extension to perform the task, as compared to not using it and making all fine-grained calls through the interoperability layer.
Although not demonstrated here, writing a custom extension to the ArcGIS Server and consuming it through a Java client over the network is similar to the steps involved in extending ArcGIS Engine.

Additional Requirements
  • Be familiar with ArcObjects and writing a C++ and COM component.
  • Before using the code examples referenced in this topic, change the file paths in the source code to the applicable paths on your machine.