0

I need to use in my C# code a method in a C++ DLL that was compiled in MATLAB.

There are a couple of DLLs, each has a method I need.

My assignment is to make a C# UI (Win form would be fine) that will will call this two methods which of course need to be given parameters: image and matrix.

extern LIB_alignment_C_API 
bool MW_CALL_CONV mlxAlignLine(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);

extern LIB_libfindLines_C_API 
bool MW_CALL_CONV mlxFindLines(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);

List of filess: https://drive.google.com/file/d/0B-5Uh7wgKQPzYV8wbEFLSjBfbTA/edit?usp=sharing


here are the H files code:

alignment.h:

//
// MATLAB Compiler: 5.1 (R2014a)
// Date: Thu Jun 12 08:45:08 2014
// Arguments: "-B" "macro_default" "-v" "-W" "cpplib:alignment" "-T" "link:lib"
// "alignLine" 
//

#ifndef __alignment_h
#define __alignment_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

#if defined(__SUNPRO_CC)
/* Solaris shared libraries use __global, rather than mapfiles
 * to define the API exported from a shared library. __global is
 * only necessary when building the library -- files including
 * this header file to use the library do not need the __global
 * declaration; hence the EXPORTING_<library> logic.
 */

#ifdef EXPORTING_alignment
#define PUBLIC_alignment_C_API __global
#else
#define PUBLIC_alignment_C_API /* No import statement needed. */
#endif

#define LIB_alignment_C_API PUBLIC_alignment_C_API

#elif defined(_HPUX_SOURCE)

#ifdef EXPORTING_alignment
#define PUBLIC_alignment_C_API __declspec(dllexport)
#else
#define PUBLIC_alignment_C_API __declspec(dllimport)
#endif

#define LIB_alignment_C_API PUBLIC_alignment_C_API


#else

#define LIB_alignment_C_API

#endif

/* This symbol is defined in shared libraries. Define it here
 * (to nothing) in case this isn't a shared library. 
 */
#ifndef LIB_alignment_C_API 
#define LIB_alignment_C_API /* No special import/export declaration */
#endif

extern LIB_alignment_C_API 
bool MW_CALL_CONV alignmentInitializeWithHandlers(
       mclOutputHandlerFcn error_handler, 
       mclOutputHandlerFcn print_handler);

extern LIB_alignment_C_API 
bool MW_CALL_CONV alignmentInitialize(void);

extern LIB_alignment_C_API 
void MW_CALL_CONV alignmentTerminate(void);



extern LIB_alignment_C_API 
void MW_CALL_CONV alignmentPrintStackTrace(void);

extern LIB_alignment_C_API 
bool MW_CALL_CONV mlxAlignLine(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);


#ifdef __cplusplus
}
#endif

#ifdef __cplusplus

/* On Windows, use __declspec to control the exported API */
#if defined(_MSC_VER) || defined(__BORLANDC__)

#ifdef EXPORTING_alignment
#define PUBLIC_alignment_CPP_API __declspec(dllexport)
#else
#define PUBLIC_alignment_CPP_API __declspec(dllimport)
#endif

#define LIB_alignment_CPP_API PUBLIC_alignment_CPP_API

#else

#if !defined(LIB_alignment_CPP_API)
#if defined(LIB_alignment_C_API)
#define LIB_alignment_CPP_API LIB_alignment_C_API
#else
#define LIB_alignment_CPP_API /* empty! */ 
#endif
#endif

#endif

extern LIB_alignment_CPP_API void MW_CALL_CONV alignLine(int nargout, mwArray& globalOffsets, mwArray& warped_ref, const mwArray& scriptImgLine, const mwArray& textImgLine, const mwArray& rectData);

#endif
#endif

libfindLines.h:

//
// MATLAB Compiler: 5.1 (R2014a)
// Date: Thu Jun 12 08:46:31 2014
// Arguments: "-B" "macro_default" "-v" "-W" "cpplib:libfindLines" "-T"
// "link:lib" "findLines" 
//

#ifndef __libfindLines_h
#define __libfindLines_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

#if defined(__SUNPRO_CC)
/* Solaris shared libraries use __global, rather than mapfiles
 * to define the API exported from a shared library. __global is
 * only necessary when building the library -- files including
 * this header file to use the library do not need the __global
 * declaration; hence the EXPORTING_<library> logic.
 */

#ifdef EXPORTING_libfindLines
#define PUBLIC_libfindLines_C_API __global
#else
#define PUBLIC_libfindLines_C_API /* No import statement needed. */
#endif

#define LIB_libfindLines_C_API PUBLIC_libfindLines_C_API

#elif defined(_HPUX_SOURCE)

#ifdef EXPORTING_libfindLines
#define PUBLIC_libfindLines_C_API __declspec(dllexport)
#else
#define PUBLIC_libfindLines_C_API __declspec(dllimport)
#endif

#define LIB_libfindLines_C_API PUBLIC_libfindLines_C_API


#else

#define LIB_libfindLines_C_API

#endif

/* This symbol is defined in shared libraries. Define it here
 * (to nothing) in case this isn't a shared library. 
 */
#ifndef LIB_libfindLines_C_API 
#define LIB_libfindLines_C_API /* No special import/export declaration */
#endif

extern LIB_libfindLines_C_API 
bool MW_CALL_CONV libfindLinesInitializeWithHandlers(
       mclOutputHandlerFcn error_handler, 
       mclOutputHandlerFcn print_handler);

extern LIB_libfindLines_C_API 
bool MW_CALL_CONV libfindLinesInitialize(void);

extern LIB_libfindLines_C_API 
void MW_CALL_CONV libfindLinesTerminate(void);



extern LIB_libfindLines_C_API 
void MW_CALL_CONV libfindLinesPrintStackTrace(void);

extern LIB_libfindLines_C_API 
bool MW_CALL_CONV mlxFindLines(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);


#ifdef __cplusplus
}
#endif

#ifdef __cplusplus

/* On Windows, use __declspec to control the exported API */
#if defined(_MSC_VER) || defined(__BORLANDC__)

#ifdef EXPORTING_libfindLines
#define PUBLIC_libfindLines_CPP_API __declspec(dllexport)
#else
#define PUBLIC_libfindLines_CPP_API __declspec(dllimport)
#endif

#define LIB_libfindLines_CPP_API PUBLIC_libfindLines_CPP_API

#else

#if !defined(LIB_libfindLines_CPP_API)
#if defined(LIB_libfindLines_C_API)
#define LIB_libfindLines_CPP_API LIB_libfindLines_C_API
#else
#define LIB_libfindLines_CPP_API /* empty! */ 
#endif
#endif

#endif

extern LIB_libfindLines_CPP_API void MW_CALL_CONV findLines(int nargout, mwArray& linesFound, mwArray& locs, const mwArray& imageMat);

#endif
#endif

2 Answers 2

1

There was a post and a project about how to do this, but I believe it is deleted due to mathworks has a product about it.

The first thing you would do in your c# project is to initialize the mcr by using PInvoke (regardless which library you will use):

[DllImport(@"mclmcrrt7_17.dll", EntryPoint = "mclInitializeApplication_proxy", CallingConvention = CallingConvention.Cdecl)]
private static extern bool mclInitializeApplication(string options, Int32 count);

and of course, terminate the mcr in the end

[DllImport(@"mclmcrrt7_17.dll", EntryPoint = "mclTerminateApplication_proxy", CallingConvention = CallingConvention.Cdecl)]
private static extern void mclTerminateApplication();   

And then look at your c file, find a method is called "your library name"+ Initialize, use it right after your mcr initialization:

[DllImport("libmcc.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool _libmccInitialize();

note: there is a little different about the method name depending on which compiler do you use, pure mcc command line compiling or deploytool, I would suggest to use dll export viewer to find real method name:http://www.nirsoft.net/utils/dll_export_viewer.html

After initialization for both methods, you can use your matlab functions:

[DllImport("libmcc.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool _mlfCreat_smallsample (int nargout, ref IntPtr sample);

Note:if you want to pass any parameter to your matlab function, you should create a pointer to this parameter in c#, here is a method that you can get the pointer of a double number

[DllImport(@"libmx.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr mxCreateDoubleScalar([In]double value);
Sign up to request clarification or add additional context in comments.

Comments

0

Make sure you built the Dll using matlab builder for .NET. Once you have done this, register the DLL by doing: start > run > regsvr32 "c:\full_path_to\your.dll"

Then, in Visual Studio right click project, add reference, on the tabs move from framework to COM and search for your DLL. You will get an interop in the references.

Access the methods on the DLL by implementing a class for it

public class myMatlab : theReferencedClassName
{
    public void methodRunner()
    {
        return base.DesiredMethodOnDll();
    }
}

Hope this helps!

2 Comments

Thanks for the help. It was my first attempt but like I said in the post, I don't have the code and the one with it cannot build it for .NET due to lack of license.
If the information was helpful on what to do vote it as an answer to help others (and my rep)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.