如何在C#中使用由MATLAB编译的C ++ DLL

时间:2014-06-15 19:58:36

标签: c# c++ matlab dll

我需要在C#代码中使用在MATLAB中编译的C ++ DLL中的方法。

有几个DLL,每个都有我需要的方法。

我的任务是制作一个C#UI(Win表格没问题),这将调用这两个方法当然需要给出参数:image和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[]);

档案清单: https://drive.google.com/file/d/0B-5Uh7wgKQPzYV8wbEFLSjBfbTA/edit?usp=sharing


这里是H文件代码:

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 个答案:

答案 0 :(得分:1)

有关于如何执行此操作的帖子和项目,但我认为由于mathworks有关于它的产品而将其删除。

您在c#项目中要做的第一件事是使用PInvoke初始化mcr(无论您将使用哪个库):

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

当然,最后终止mcr

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

然后查看你的c文件,找到一个名为&#34;你的库名称&#34; +初始化的方法,在你的mcr初始化后立即使用它:

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

注意:根据您使用的编译器,纯mcc命令行编译或deploytool,方法名称略有不同,我建议使用dll export viewer查找实际方法名称:http://www.nirsoft.net/utils/dll_export_viewer.html < / p>

在两种方法初始化之后,您可以使用matlab函数:

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

注意:如果你想将任何参数传递给你的matlab函数,你应该在c#中创建一个指向这个参数的指针,这里有一个方法可以得到一个双数字的指针

[DllImport(@"libmx.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr mxCreateDoubleScalar([In]double value);

答案 1 :(得分:0)

确保使用适用于.NET的matlab构建器构建了Dll。完成此操作后,通过执行以下操作注册DLL:start&gt;运行&gt; regsvr32&#34; c:\ full_path_to \ your.dll&#34;

然后,在Visual Studio中右键单击项目,添加引用,在选项卡上从框架移动到COM并搜索您的DLL。您将在参考文献中获得互操作。

通过为它实现一个类来访问DLL上的方法

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

希望这有帮助!