C++ and .NET Library Differences
The WMX3 libraries are provided in two main packages: as a C++ library and as a .NET library. Almost all functions that are available in the C++ library can be called from the .NET library, and the majority of API functions have the same name and interface in both C++ and .NET. However, there are a few areas where the interfaces differ between the two libraries. The API Reference discusses functions using the C++ interface. Users of the .NET library languages (such as C#, VB.NET, and C++/CLI) should keep the following differences in mind:
IDisposable
The main library class of WMX3 (WMX3Api) and the main library classes of each WMX3 module (such as CoreMotion) inherit the IDisposable class. Because of this, for each instance of this class, the Dispose function must be called when that object can be freed. This is often immediately after the CloseDevice function is called (unless the closed device will call CreateDevice at a later time).
Failing to call the function at the appropriate time may cause the .NET garbage collector to release unmanaged resources prematurely, resulting in undefined behavior.
The following is an example of how the Dispose function should be called.
WMX3Api wmxlib = new WMX3Api();
CoreMotion wmxlib_cm = new CoreMotion(wmxlib);
wmxlib.CreateDevice("C:\\Program Files\\SoftServo\\WMX3", DeviceType.DeviceTypeNormal);
//Call functions from wmxlib and wmxlib_cm
wmxlib.CloseDevice();
wmxlib_cm.Dispose();
wmxlib.Dispose();
Namespaces
The wmx3Api namespace of the C++ library is named WMX3ApiCLR in the .NET library. The wmx3Api::simuApi namespace of the C++ library is named WMX3ApiCLR.SimuApiCLR in the .NET library. Namespaces of other platforms follow the same convention, capitalizing the first letter of the namespace name and appending “CLR”.
Member Variables
Member variables of classes in the C++ library start with lowercase letters. Member variables of classes in the .NET library have the same name as their equivalents in the C++ library, but the first letter is capitalized.
Example:
C++ Library:
class Profile {
ProfileType::T type;
double velocity;
double acc;
double dec;
double jerkAcc;
double jerkDec;
double jerkAccRatio;
double jerkDecRatio;
double accTimeMilliseconds;
double decTimeMilliseconds;
double startingVelocity;
double endVelocity;
double secondVelocity;
double movingAverageTimeMilliseconds;
}
.NET Library:
public ref class Profile{
ProfileType Type;
double Velocity;
double Acc;
double Dec;
double JerkAcc;
double JerkDec;
double JerkAccRatio;
double JerkDecRatio;
double AccTimeMilliseconds;
double DecTimeMilliseconds;
double StartingVelocity;
double EndVelocity;
double SecondVelocity;
double MovingAverageTimeMilliseconds;
};
char*, wchar_t* vs String
Several functions in the WMX3 library have string parameters. In the C++ library, these string parameters have the char* or wchar_t* type (a null-terminated array of char or wchar_t types), and two functions are defined, one for each of char* and wchar_t*. In the .NET library, these string parameters have the String type, and only one function is defined.
Example:
C++ Library:
SetDeviceName(const char* name);
SetDeviceName(const wchar_t* name);
.NET Library:
SetDeviceName(String^ name);
Default Parameters
A number of functions in the C++ library have default parameters that allow these parameters to be optionally specified. The .NET library will instead define a separate function, one with the parameter and one without. The function without the parameter will use the same default value for the parameter as the C++ library.
Example:
C++ Library:
CreateDevice(const char* path, DeviceType::T type, unsigned int waitTimeMilliseconds = 0, int core = -1, DWORD_PTR affinityMask = 0);
.NET Library:
CreateDevice(String ^pPath, DeviceType type);
CreateDevice(String ^pPath, DeviceType type, unsigned int waitTimeMilliseconds);
CreateDevice(String ^pPath, DeviceType type, unsigned int waitTimeMilliseconds, int core);
CreateDevice(String ^pPath, DeviceType type, unsigned int waitTimeMilliseconds, int core, DWORD_PTR affinityMask);
Unions vs Child Classes
A few classes in the C++ library have union members that allow the same class to contain one of several sets of data. The .NET library will instead define a different class for each union member, and provide a property interface so that any of these classes can be accessed using a syntax similar to unions. These classes that replace union types are only instantiated when they are accessed for the first time, so like unions, there is no large memory requirement.
Example:
C++ Library:
TriggerEvent trig;
//input is an union of type TriggerEventInputFunctionArguments
trig.input.ioBit.byteAddress = 10;
trig.input.ioBit.bitAddress = 2;
trig.inputFunction = TriggerEventInputFunction::IOBit;
.NET Library:
TriggerEvent trig = new TriggerEvent();
//Input_IOBit is a property for accessing the class
trig.Input_IOBit.ByteAddress = 10;
trig.Input_IOBit.BitAddress = 2;
trig.InputFunction = TriggerEventInputFunction.IOBit;
Size of Arrays
A few functions in the C++ library have a parameter that takes an array that will be filled in with data and another parameter that specifies the size of that array. The .NET library will only have an array parameter, as the array object itself will contain information about the size of the array.
Example:
C++ Library:
UploadSDO(int slaveId, int index, int subindex, int sdoBuffSize, unsigned char sdoBuff, unsigned int actualSize, unsigned int* errCode, unsigned int waitTime);
.NET Library:
UploadSDO(int index, int subindex, array<byte> ^sdoBuff, unsigned int %actualSize, unsigned int %errCode, unsigned int waitTime);
Constants
Constants in the C++ library are defined globally in the constants workspace. The constants of each module are defined in the header file of that module.
For the .NET library, these constants are defined in the [Module Name]Constants class. For example, the constants of the API Buffer module are defined in the ApiBufferConstants class. The basic constants of WMX3 are defined in the Constants class.
See Constants for information regarding the constants of each module.
Example:
C++ Library:
constants::maxAxes
.NET Library:
Constants.MaxAxes
String Type Return Values
Several functions return strings differently based on whether the function is called from the C++ library or the .NET library. The C++ library function returns the string through a parameter of the function, while the .NET library function returns a String object as the function return value.
ErrorToString
The ErrorToString function that is defined in each module returns a string representation of an error code.
C++ Library:
static long ErrorToString(int errCode, char *pString, unsigned int size);
static long ErrorToString(int errCode, wchar_t *pString, unsigned int size);
.NET Library:
static String^ ErrorToString(int errCode);
ApiLogToString
The ApiLogToString function that is defined in each module converts raw data from the API log to a string representation of the data. Also, the C++ library requires the size of the raw data to be specified, but the .NET library does not.
C++ Library:
static long ApiLogToString(unsigned char* pLogData, unsigned int logDataSize, char *pString, unsigned int size);
static long ApiLogToString(unsigned char* pLogData, unsigned int logDataSize, wchar_t *pString, unsigned int size);
.NET Library:
static String^ ApiLogToString(array<byte>^ pApiLogData);
TimestampToString
The TimestampToString function that is defined in the Log module returns a string representation of the timestamp member of the ApiLogInfo class.
C++ Library:
static long TimestampToString(long long timestamp, char *pString, unsigned int size);
static long TimestampToString(long long timestamp, wchar_t *pString, unsigned int size);
.NET Library:
static String^ TimestampToString(long long timestamp);
FILE class
For functions that use the FILE class in the C++ library, the equivalent function in the .NET library uses the WMX3File class defined in the WMX3ApiCLR namespace. This WMX3File class encapsulates the FILE class.