MATLAB Answers

deploy c++ shared library, generated from matlab, in cpp

12 views (last 30 days)
Kun-Lin Hsieh
Kun-Lin Hsieh on 1 Jun 2020
Answered: Chidvi Modala on 8 Jul 2020
I used the sample code, provided from MyAdd_test_example, and followed the steps to obtain a c++ shared library generated from matlab. Following the illustrations, I could successfully get "libMyAdd.h/dll/lib", and compilied the cpp file, as shown below, into an exe file with the command "mbuild MyAdd_test.cpp libMyAdd.lib -v" in matlab. However, while following the steps, presented in MyAdd_test_example, to compile the cpp file in Visual Studio, an error happened with "LNK2019 unresolved external symbol "__declspec(dllimport) void __cdecl MyAdd(int,class mwArray &,class mwArray const &,class mwArray const &)" (__imp_?MyAdd@@YAXHAEAVmwArray@@AEBV1@1@Z)main".
Here is my enviroment:
  1. matlab 2018b 64-bit
  2. win10
  3. visual studio 2019
I've followed the steps to set all the necessary path, including the .lib and .h path. However, I still can't compile the cpp in visual studio ,but succesfully in matlab.
I also found something strange that "MyAdd" function can be found in the .h file. However the .dll file contains no such the file but mlxMyAdd only.
Since the cpp file can be compiled in matlab, I think the syntax of the cpp should be correct. The problem I met is why the cpp file can't be compiled in Visual Studio...
#include "libMyAdd.h"
int main()
{
// initialize MCR and lib
if (!mclInitializeApplication(NULL,0)) {
std::cerr << "could not initialize the application" << std::endl;
return -1;
}
if(!libMyAddInitialize()) {
std::cerr << "Could not initialize the library" << std::endl;
return -1;
}
try {
// create input
double a[] = {1.0, 2.0, 3.0, 4.0};
double b[] = {5.0, 6.0, 7.0, 8.0};
mwArray in1(2, 2, mxDOUBLE_CLASS, mxREAL);
mwArray in2(2, 2, mxDOUBLE_CLASS, mxREAL);
in1.SetData(a, 4);
in2.SetData(b, 4);
// call function
mwArray out;
MyAdd(1, out, in1, in2);
// show result
std::cout << "in1 + in2 = " << std::endl;
std::cout << out << std::endl;
double c[4];
out.GetData(c, 4);
for(int i=0; i<4; i++) {
std::cout << c[i] << " " << std::endl;
}
} catch (const mwException& e) {
std::cerr << e.what() << std::endl;
return -2;
} catch (...) {
std::cerr << "Unexpected error thrown" << std::endl;
return -3;
}
// cleanup
libMyAddTerminate();
mclTerminateApplication();
return 0;
}
// libMyAdd.h
//
// MATLAB Compiler: 7.0 (R2018b)
// Date: Fri May 29 18:35:42 2020
// Arguments:
// "-B""macro_default""-N""-W""cpplib:libMyAdd""-T""link:lib""MyAdd.m""-v"
//
#ifndef __libMyAdd_h
#define __libMyAdd_h 1
#if defined(__cplusplus) && !defined(mclmcrrt_h) && defined(__linux__)
# pragma implementation "mclmcrrt.h"
#endif
#include "mclmcrrt.h"
#include "mclcppclass.h"
#ifdef __cplusplus
extern "C" {
#endif
/* This symbol is defined in shared libraries. Define it here
* (to nothing) in case this isn't a shared library.
*/
#ifndef LIB_libMyAdd_C_API
#define LIB_libMyAdd_C_API /* No special import/export declaration */
#endif
/* GENERAL LIBRARY FUNCTIONS -- START */
extern LIB_libMyAdd_C_API
bool MW_CALL_CONV libMyAddInitializeWithHandlers(
mclOutputHandlerFcn error_handler,
mclOutputHandlerFcn print_handler);
extern LIB_libMyAdd_C_API
bool MW_CALL_CONV libMyAddInitialize(void);
extern LIB_libMyAdd_C_API
void MW_CALL_CONV libMyAddTerminate(void);
extern LIB_libMyAdd_C_API
void MW_CALL_CONV libMyAddPrintStackTrace(void);
/* GENERAL LIBRARY FUNCTIONS -- END */
/* C INTERFACE -- MLX WRAPPERS FOR USER-DEFINED MATLAB FUNCTIONS -- START */
extern LIB_libMyAdd_C_API
bool MW_CALL_CONV mlxMyAdd(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);
/* C INTERFACE -- MLX WRAPPERS FOR USER-DEFINED MATLAB FUNCTIONS -- END */
#ifdef __cplusplus
}
#endif
/* C++ INTERFACE -- WRAPPERS FOR USER-DEFINED MATLAB FUNCTIONS -- START */
#ifdef __cplusplus
/* On Windows, use __declspec to control the exported API */
#if defined(_MSC_VER) || defined(__MINGW64__)
#ifdef EXPORTING_libMyAdd
#define PUBLIC_libMyAdd_CPP_API __declspec(dllexport)
#else
#define PUBLIC_libMyAdd_CPP_API __declspec(dllimport)
#endif
#define LIB_libMyAdd_CPP_API PUBLIC_libMyAdd_CPP_API
#else
#if !defined(LIB_libMyAdd_CPP_API)
#if defined(LIB_libMyAdd_C_API)
#define LIB_libMyAdd_CPP_API LIB_libMyAdd_C_API
#else
#define LIB_libMyAdd_CPP_API /* empty! */
#endif
#endif
#endif
extern LIB_libMyAdd_CPP_API void MW_CALL_CONV MyAdd(int nargout, mwArray& c, const mwArray& a, const mwArray& b);
/* C++ INTERFACE -- WRAPPERS FOR USER-DEFINED MATLAB FUNCTIONS -- END */
#endif
#endif

  0 Comments

Sign in to comment.

Answers (1)

Chidvi Modala
Chidvi Modala on 8 Jul 2020
These link errors might occur because Visual C++ by default builds projects to target 32 bit platforms however you are using a 64 bit MATLAB.
So, you can configure VC++ to target 64 bit platforms first. You can refer to this link for the steps on how to do

  0 Comments

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!