Softimage SDK Programmer's Guide > C++ API Development > Programming with the C++ API >

# Migrating Legacy Plug-ins

Softimage continues to support legacy C++ commands, but because of the rich feature set and the improved workflow associated with self-installed custom commands you should really take the time to port them to the new mechanism. The good news is that the actual implementation of your code does not need to change significantly.

One way to port your Custom Command to Softimage is to create a new command using the SDK Command Wizard (see Custom Command Wizard for more information) and then copy and paste your actual implementation into the new dll. However it is also easy to do this manually. For the purpose of this example, assume that your command in called Foo.

## To port a legacy C++ command to a self-installed plugin.

1. Back up your source files.

2. In Softimage make sure that any old version of the command has been removed by running the following code snippet in the Script Editor:

       // JScript
       Application.RemoveCommand( "Foo" );

3. For Windows, instead of using a .def file to export functions, add the XSIPLUGINCALLBACK macro to the function definition:

       XSIPLUGINCALLBACK CStatus XSILoadPlugin( PluginRegistrar& in_reg )

4. In your .cpp file add a XSILoadPlugin callback function similar to this:

       	#ifdef unix
       	extern "C"
       	#endif
       	XSIPLUGINCALLBACK CStatus XSILoadPlugin( PluginRegistrar& in_reg )
       	{
       		in_reg.PutAuthor(L"My Name");
       		in_reg.PutName(L"foo Plug-in");
       		in_reg.PutVersion(1,0);
       		in_reg.RegisterCommand(L"Foo",L"Foo");

       		return CStatus::OK;
       	}

   Note

   For more information on this callback and more about self-installing plug-ins in general, see Self-Installing Plug-ins.

5. Add another callback function called Foo_Init. This function replaces your old installation script which probably looked like this.

       	'OBSOLETE:
       	SUB InstallFooDemo( dllDir, ext )
       		Module="Foo"
       		filename = dllDir & "/" & Module & ext

       		Application.RemoveCommand "Foo"
       		SET oCmd = Application.CreateCommand("Foo",siNoCategory)
       		oCmd.ScriptingName = "Foo"
       		oCmd.FileName = filename
       		oCmd.Language = "CPP"

       		oCmd.arguments.add "Arg0", siArgumentInput
       		oCmd.arguments.addObjectArgument "Arg1"

       		' Add the new command
       		Application.AddCommand oCmd
       	END SUB

   The new Foo_Init function is where you define the arguments and the flags for your command. The C++ API for defining a command is very similar to the Object Model API that you used in your install script so porting your code should not be too difficult. See the Argument and Command classes for more details.

   Here is an example of what your Foo_Init function could look like:

       	#ifdef unix
       	extern "C"
       	#endif
       	XSIPLUGINCALLBACK CStatus Foo_Init( CRef& in_ctxt )
       	{
       		Context ctxt( in_ctxt );
       		Command oCmd;
       		oCmd = ctxt.GetSource();
       		oCmd.PutDescription(L"Foo does important stuff");
       		oCmd.EnableReturnValue(true);

       		ArgumentArray oArgs;
       		oArgs = oCmd.GetArguments();
       		oArgs.Add(L"Arg0");
       		oArgs.AddObjectArgument(L"Arg1");
       		return CStatus::OK;
       	}

6. Once you are done writing your Foo_Init function, remove the old install script code.

7. Now you need to replace the old XSIOnCommandCPP callback with the new Foo_Execute callback function. Your old code:

       	#ifdef unix
       	extern "C"
       	#endif
       	XSI::CStatus XSIOnCommandCPP
       	(
       		const XSI::CString&	in_strCmdName, // name of the command
       		XSI::CValueArray&	args, // array of arguments
       		XSI::CValue&		io_retVal		// return value
       	)
       	{
       		...
       	}

   becomes:

       	#ifdef unix
       	extern "C"
       	#endif
       	XSIPLUGINCALLBACK CStatus foo_Execute( CRef& in_ctxt )
       	{
       		Context ctxt( in_ctxt );
       		CValueArray args = ctxt.GetAttribute(L"Arguments");
       		...
       	}

   Note

   There is no io_retVal argument anymore, instead you can return a value like this:

       	CValue returnValue ;
       	//...set a value in returnValue ;
       	ctxt.PutAttribute( L"ReturnValue", returnValue );

8. Compilation time. You may find that you need to add some new C++ API include statements. For example:

       	#include <xsi_context.h>
       	#include <xsi_pluginregistrar.h>
       	#include <xsi_argument.h>
       	#include <xsi_command.h>

9. Now you just need to make sure your dll is in the correct path, for example in the "\Application\Plugins" directory on your workgroup. You can use the Plugin Manager to load/reload the dll without restarting Softimage (see Working with the Plug-in Manager for more information).

10. Invoke your command in the Script Editor to test it and that's it!

## Multiple commands

The preceding procedure only covers the case of a single command in a .dll or .so. However you can easily have multiple commands implemented in your self-installing plug-in dll. Just register them in your XSILoadPlugin implementation, and add an Init and Execute function for each one.

You can use the Command Wizard to add commands to a plug-in. In the script editor, right-click and choose Tools Add Command.