Previous page

Next page

Locate page in Contents

Compiling with SdkWrap

When using SdkWrap, your program must contain the following:

  • The #include "SdkWrap.h" directive. This header file defines the wrapper functions.
  • The #define SDK_LIB_NAME "libprl_sdk.dylib" directive. This is the name of the dynamic library included in the SDK.
  • The SdkWrap_Load(SDK_LIB_NAME) function call that will load the dynamic library symbols.
  • The SdkWrap_Unload() function call that will unload the dynamic library when it is no longer needed.

To compile a program, the following compiler options and instructions must be used:

  • The DYN_API_WRAP preprocessor macro must be defined.
  • Full paths to the Headers and the Helpers/SdkWrap directories must be specified. Both directories are located in the main SDK installation directory.
  • The SdkWrap.cpp file must be included in the project and must be built together with the main target.
  • The libdl library must be linked to the application. This is the standard dynamic linking interface library needed to load the SDK library.

Using Makefile

The following is a sample Makefile that demonstrates the implementation of the requirements described above. To compile a program and to build an executable, type make in the Terminal window. To clean up the project, type make clean. Please note that the SOURCE variable must contain the name of your source file name.

# Source file name.

# Substitute the file name with your own.

SOURCE = HelloWorld

    

# Target executable file name.

# Here we are using the same name as the source file name.

TARGET = $(SOURCE)

  

# Path to the Parallels Virtualization SDK files.

SDK_PATH = /Library/Frameworks/ParallelsVirtualizationSDK.framework

  

# Relative path to the SdkWrap directory containing

# the SDK helper files. The files are used to load

# the dynamic library.

SDK_WRAP_PATH = Helpers/SdkWrap

  

OBJS = SdkWrap.o $(SOURCE).o

CXX = g++

CXXFLAGS = -DDYN_API_WRAP -I$(SDK_PATH)/Headers -I$(SDK_PATH)/$(SDK_WRAP_PATH)

LDFLAGS = -ldl

  

all : $(TARGET)

  

$(TARGET) : $(OBJS)

$(CXX) -o $@ $(LDFLAGS) $(OBJS)

  

$(SOURCE).o : $(SOURCE).cpp

$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE).cpp

  

SdkWrap.o : $(SDK_PATH)/$(SDK_WRAP_PATH)/SdkWrap.cpp

$(CXX) -c -o $@ $(CXXFLAGS) $(SDK_PATH)/$(SDK_WRAP_PATH)/SdkWrap.cpp

  

clean:

@rm -f $(OBJS) $(TARGET)

  

.PHONY : all clean

Using Xcode IDE

If you are using the Xcode IDE, follow these steps to set up your project:

  1. Add the SdkWrap.h and the SdkWrap.cpp files to your project.
  2. In the Search Paths collection, specify:
    • a full path to the Helpers/SdkWrap directory (contains the wrapper source files)
    • a full path to the Headers directory (contains the SDK header files)
    • a full path to the Libraries directory (contains the dynamic library)
  3. In the Preprocessor collection, add the DYN_API_WRAP preprocessor macro.

Example

The following is a complete sample program that demonstrates the usage of the SdkWrap wrapper. The program loads the dynamic library, initializes the API, and then logs in to the local Parallels Service. You can copy the entire program into a file on your Mac and try building and then running it. The program uses a cross-platform approach, so it can also be compiled on Windows and Linux machines.

#include "SdkWrap.h"

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

  

#ifdef _WIN_

#include <windows.h>

#else

#include <unistd.h>

#endif

  

PRL_RESULT LoginLocal(PRL_HANDLE &hServer);

PRL_RESULT LogOff(PRL_HANDLE &hServer);

  

/////////////////////////////////////////////////////////////////////

  

int main(int argc, char* argv[])

{

    // Variables for handles.

    PRL_HANDLE hJob = PRL_INVALID_HANDLE; // job handle

    PRL_HANDLE hJobResult = PRL_INVALID_HANDLE; // job result

    PRL_HANDLE hServer = PRL_INVALID_HANDLE;    // server handle

  

    // Variables for return codes.

    PRL_RESULT err = PRL_ERR_UNINITIALIZED;

    PRL_RESULT nJobReturnCode = PRL_ERR_UNINITIALIZED;

  

    // Log in to Parallels Service.

    err = LoginLocal(hServer);

  

    // Log off.

    err = LogOff(hServer);

  

    printf( "\nEnd of program.\n\n" );

    printf("Press Enter to exit...");

    getchar();

  

    exit(0);

}

  

// Initializes the SDK library and

// logs in to the local Parallels Service.

//

PRL_RESULT LoginLocal(PRL_HANDLE &hServer)

{

    // Variables for handles.

    PRL_HANDLE hJob = PRL_INVALID_HANDLE; // job handle

    PRL_HANDLE hJobResult = PRL_INVALID_HANDLE; // job result

  

    // Variables for return codes.

    PRL_RESULT err = PRL_ERR_UNINITIALIZED;

    PRL_RESULT nJobReturnCode = PRL_ERR_UNINITIALIZED;

  

    // Use the correct dynamic library depending on the platform.

    #ifdef _WIN_

    #define SDK_LIB_NAME "prl_sdk.dll"

    #elif defined(_LIN_)

    #define SDK_LIB_NAME "libprl_sdk.so"

    #elif defined(_MAC_)

    #define SDK_LIB_NAME "libprl_sdk.dylib"

    #endif

  

    // Load SDK library.

    if (PRL_FAILED(SdkWrap_Load(SDK_LIB_NAME)) &&

        PRL_FAILED(SdkWrap_Load("./" SDK_LIB_NAME)))

    {

        fprintf( stderr, "Failed to load " SDK_LIB_NAME "\n" );

        return -1;

    }

  

    // Initialize the API. In this example, we are initializing the

    // API for Parallels Desktop.

    // To initialize in the Parallels Workstation mode, pass PAM_WORKSTATION

    // as the second parameter.

    // To initialize for Parallels Server, pass PAM_SERVER.

    // See the PRL_APPLICATION_MODE enumeration for all possible options.

    err = PrlApi_InitEx(PARALLELS_API_VER, PAM_DESKTOP, 0, 0);

  

    if (PRL_FAILED(err))

    {

        fprintf(stderr, "PrlApi_InitEx returned with error: %s.\n",

            prl_result_to_string(err));

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

  

    // Create a server handle (PHT_SERVER).

    err = PrlSrv_Create(&hServer);

    if (PRL_FAILED(err))

    {

        fprintf(stderr, "PrlSvr_Create failed, error: %s",

            prl_result_to_string(err));

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

  

    // Log in (asynchronous call).

    hJob = PrlSrv_LoginLocal(hServer, NULL, NULL, PSL_NORMAL_SECURITY);

  

    // Wait for a maximum of 10 seconds for

    // the job to complete.

    err = PrlJob_Wait(hJob, 1000);

    if (PRL_FAILED(err))

    {

        fprintf(stderr,

            "PrlJob_Wait for PrlSrv_Login returned with error: %s\n",

            prl_result_to_string(err));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

  

    // Analyze the result of PrlSrv_Login.

    err = PrlJob_GetRetCode(hJob, &nJobReturnCode);

  

    // First, check PrlJob_GetRetCode success/failure.

    if (PRL_FAILED(err))

    {

        fprintf(stderr, "PrlJob_GetRetCode returned with error: %s\n",

            prl_result_to_string(err));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

  

    // Now check the Login operation success/failure.

    if (PRL_FAILED(nJobReturnCode))

    {

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        printf("Login job returned with error: %s\n",

            prl_result_to_string(nJobReturnCode));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

    else

    {

        printf( "Login was successful.\n" );

    }

  

    return 0;

}

  

// Logs off the Parallels Service and

// deinitializes the SDK library.

//

PRL_RESULT LogOff(PRL_HANDLE &hServer)

{

    PRL_HANDLE hJob = PRL_INVALID_HANDLE;

    PRL_HANDLE hJobResult = PRL_INVALID_HANDLE;

  

    PRL_RESULT err = PRL_ERR_UNINITIALIZED;

    PRL_RESULT nJobReturnCode = PRL_ERR_UNINITIALIZED;

  

    // Log off.

    hJob = PrlSrv_Logoff(hServer);

    err = PrlJob_Wait(hJob, 1000);

    if (PRL_FAILED(err))

    {

        fprintf(stderr, "PrlJob_Wait for PrlSrv_Logoff returned error: %s\n",

            prl_result_to_string(err));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

  

    // Get the Logoff operation return code.

    err = PrlJob_GetRetCode(hJob, &nJobReturnCode);

  

    // Check the PrlJob_GetRetCode success/failure.

    if (PRL_FAILED(err))

    {

        fprintf(stderr, "PrlJob_GetRetCode failed for PrlSrv_Logoff with error: %s\n",

            prl_result_to_string(err));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

  

    // Report success or failure of PrlSrv_Logoff.

    if (PRL_FAILED(nJobReturnCode))

    {

        fprintf(stderr, "PrlSrv_Logoff failed with error: %s\n",

            prl_result_to_string(nJobReturnCode));

        PrlHandle_Free(hJob);

        PrlHandle_Free(hServer);

        PrlApi_Deinit();

        SdkWrap_Unload();

        return -1;

    }

    else

    {

        printf( "Logoff was successful.\n" );

    }

  

    // Free handles that are no longer required.

    PrlHandle_Free(hJob);

    PrlHandle_Free(hServer);

  

    // De-initialize the Parallels API, and unload the SDK.

    PrlApi_Deinit();

    SdkWrap_Unload();

  

    return 0;

}