This example shows how to write a MATLAB®
Production Server™ client using the C client API. The client application calls the
addmatrix
function you compiled in Package Deployable Archives with Production Server Compiler App
and deployed in Share the Deployable Archive (MATLAB Production Server).
Create a C++ MATLAB Production Server client application:
Create a file called addmatrix_client.cpp
.
Using a text editor, open addmatrix_client.cpp
.
Add the following include statements to the file:
#include <iostream> #include <mps/client.h>
Note
The header files for the MATLAB
Production Server C client API are located in the
folder. folder.matlabroot
/toolbox/compiler_sdk/mps_client/c/include/mps
Add the main()
method to the application.
int main ( void ) { }
Initialize the client runtime.
mpsClientRuntime* mpsruntime = mpsInitializeEx(MPS_CLIENT_1_1);
Create the client configuration.
mpsClientConfig* config; mpsStatus status = mpsruntime->createConfig(&config);
Create the client context.
mpsClientContext* context; status = mpsruntime->createContext(&context, config);
Create the MATLAB data to input to the function.
double a1[2][3] = {{1,2,3},{3,2,1}}; double a2[2][3] = {{4,5,6},{6,5,4}}; int numIn=2; mpsArray** inVal = new mpsArray* [numIn]; inVal[0] = mpsCreateDoubleMatrix(2,3,mpsREAL); inVal[1] = mpsCreateDoubleMatrix(2,3,mpsREAL); double* data1 = (double *)( mpsGetData(inVal[0]) ); double* data2 = (double *)( mpsGetData(inVal[1]) ); for(int i=0; i<2; i++) { for(int j=0; j<3; j++) { mpsIndex subs[] = { i, j }; mpsIndex id = mpsCalcSingleSubscript(inVal[0], 2, subs); data1[id] = a1[i][j]; data2[id] = a2[i][j]; } }
Create the MATLAB data to hold the output.
int numOut = 1; mpsArray **outVal = new mpsArray* [numOut];
Call the deployed MATLAB function.
Specify the following as arguments:
client context
URL of the function
Number of expected outputs
Pointer to the mpsArray
holding the outputs
Number of inputs
Pointer to the mpsArray
holding the inputs
mpsStatus status = mpsruntime->feval(context, "http://localhost:9910/addmatrix/addmatrix", numOut, outVal, numIn, (const mpsArray**)inVal);
For more information about the feval
function, see the reference
material included in the
folder.matlabroot
/toolbox/compiler_sdk/mps_client
Verify that the function call was successful using an if
statement.
if (status==MPS_OK) { }
Inside the if
statement, add code to process the output.
double* out = mpsGetPr(outVal[0]); for (int i=0; i<2; i++) { for (int j=0; j<3; j++) { mpsIndex subs[] = {i, j}; mpsIndex id = mpsCalcSingleSubscript(outVal[0], 2, subs); std::cout << out[id] << "\t"; } std::cout << std::endl; }
Add an else
clause to the if
statement to process
any errors.
else { mpsErrorInfo error; mpsruntime->getLastErrorInfo(context, &error); std::cout << "Error: " << error.message << std::endl; switch(error.type) { case MPS_HTTP_ERROR_INFO: std::cout << "HTTP: " << error.details.http.responseCode << ": " << error.details.http.responseMessage << std::endl; case MPS_MATLAB_ERROR_INFO: std::cout << "MATLAB: " << error.details.matlab.identifier << std::endl; std::cout << error.details.matlab.message << std::endl; case MPS_GENERIC_ERROR_INFO: std::cout << "Generic: " << error.details.general.genericErrorMsg << std::endl; } mpsruntime->destroyLastErrorInfo(&error); }
Free the memory used by the inputs.
for (int i=0; i<numIn; i++) mpsDestroyArray(inVal[i]); delete[] inVal;
Free the memory used by the outputs.
for (int i=0; i<numOut; i++) mpsDestroyArray(outVal[i]); delete[] outVal;
Free the memory used by the client runtime.
mpsruntime->destroyConfig(config); mpsruntime->destroyContext(context); mpsTerminate();
Save the file.
The completed program should resemble the following:
#include <iostream> #include <mps/client.h> int main ( void ) { mpsClientRuntime* mpsruntime = mpsInitializeEx(MPS_CLIENT_1_1); mpsClientConfig* config; mpsStatus status = mpsruntime->createConfig(&config); mpsClientContext* context; status = mpsruntime->createContext(&context, config); double a1[2][3] = {{1,2,3},{3,2,1}}; double a2[2][3] = {{4,5,6},{6,5,4}}; int numIn=2; mpsArray** inVal = new mpsArray* [numIn]; inVal[0] = mpsCreateDoubleMatrix(2,3,mpsREAL); inVal[1] = mpsCreateDoubleMatrix(2,3,mpsREAL); double* data1 = (double *)( mpsGetData(inVal[0]) ); double* data2 = (double *)( mpsGetData(inVal[1]) ); for(int i=0; i<2; i++) { for(int j=0; j<3; j++) { mpsIndex subs[] = { i, j }; mpsIndex id = mpsCalcSingleSubscript(inVal[0], 2, subs); data1[id] = a1[i][j]; data2[id] = a2[i][j]; } } int numOut = 1; mpsArray **outVal = new mpsArray* [numOut]; status = mpsruntime->feval(context, "http://localhost:9910/addmatrix/addmatrix", numOut, outVal, numIn, (const mpsArray **)inVal); if (status==MPS_OK) { double* out = mpsGetPr(outVal[0]); for (int i=0; i<2; i++) { for (int j=0; j<3; j++) { mpsIndex subs[] = {i, j}; mpsIndex id = mpsCalcSingleSubscript(outVal[0], 2, subs); std::cout << out[id] << "\t"; } std::cout << std::endl; } } else { mpsErrorInfo error; mpsruntime->getLastErrorInfo(context, &error); std::cout << "Error: " << error.message << std::endl; switch(error.type) { case MPS_HTTP_ERROR_INFO: std::cout << "HTTP: " << error.details.http.responseCode << ": " << error.details.http.responseMessage << std::endl; case MPS_MATLAB_ERROR_INFO: std::cout << "MATLAB: " << error.details.matlab.identifier << std::endl; std::cout << error.details.matlab.message << std::endl; case MPS_GENERIC_ERROR_INFO: std::cout << "Generic: " << error.details.general.genericErrorMsg << std::endl; } mpsruntime->destroyLastErrorInfo(&error); } for (int i=0; i<numIn; i++) mpsDestroyArray(inVal[i]); delete[] inVal; for (int i=0; i<numOut; i++) mpsDestroyArray(outVal[i]); delete[] outVal; mpsruntime->destroyConfig(config); mpsruntime->destroyContext(context); mpsTerminate(); }
Compile the application.
To compile your client code, the compiler needs access to client.h
.
This header file is stored in
.matlabroot
/toolbox/compiler_sdk/mps_client/c/include/mps/
To link your application, the linker needs access to the following files stored in
: matlabroot
/toolbox/compiler_sdk/mps_client/c/
Files Required for Linking
Windows® | UNIX®/Linux | Mac OS X |
---|---|---|
$arch\lib\mpsclient.lib | $arch/lib/libprotobuf.so | $arch/lib/libprotobuf.dylib |
$arch/lib/libcurl.so | $arch/lib/libcurl.dylib | |
$arch/lib/libmwmpsclient.so | $arch/lib/libmwmpsclient.dylib | |
$arch/lib/libmwcpp11compat.so |
Run the application.
To run your application, add the following files stored in
to
the application’s path: matlabroot
/toolbox/compiler_sdk/mps_client/c/
Files Required for Running
Windows | UNIX/Linux | Mac OS X |
---|---|---|
$arch\lib\mpsclient.dll | $arch/lib/libprotobuf.so | $arch/lib/libprotobuf.dylib |
$arch\lib\libprotobuf.dll | $arch/lib/libcurl.so | $arch/lib/libcurl.dylib |
$arch\lib\libcurl.dll | $arch/lib/libmwmpsclient.so | $arch/lib/libmwmpsclient.dylib |
$arch/lib/libmwcpp11compat.so |
The client invokes addmatrix
function on the server instance and
returns the following matrix at the console:
5.0 7.0 9.0 9.0 7.0 5.0