从c++调用MATLAB错误:无法解析的外部符号
Calling MATLAB from C++ errors: unresolved external symbol
从c++调用MATLAB函数时,我遇到了几个错误。主要思路是:首先编译MATLAB函数并生成DLL文件,然后在c++中包含。h和。lib文件。最后,编写.cpp来测试和调用该函数。这是我的详细步骤,请告诉我哪里错了。
(使用MATLAB 2012b和Visual c++ 2008, Windows 7 64位)
在MATLAB:
-
mbuild -setup
和mex -setup
设置Visual Microsoft Visual c++ 2008 SP1为编译器。 在文件夹
C:UsersWangYudongDocumentsMATLABMyAdd_M
中创建MyAdd.m
,功能如下:function [c] = MyAdd(a, b) c = a + b;
mcc -W cpplib:libMyAdd -T link:lib MyAdd
编译MyAdd.m
,生成libMyAdd.dll
、libMyAdd.h
、libMyAdd.lib
等多个文件。
选择 vc++ Directories→Include files添加
E:MATLABR2012bexterninclude
.选择 vc++ Directories→Library files添加
E:MATLABR2012bexternlibwin64microsoft
和C:UsersWangYudongDocumentsMATLABMyAdd_M
.选择 linkker →Input→Additional Dependencies添加新条目:
mclmcr.lib mclmcrrt.lib libmx.lib libmat.lib libMyAdd.lib
新建
MyAdd_test.cpp
,并将libMyAdd.dll
,libMyAdd.h
和libMyAdd.lib
放在同一个文件夹中。在头文件中增加libMyAdd.h
,在资源文件中增加libMyAdd.h
和libMyAdd.lib
。
MyAdd_test.cpp
的代码如下:
#include "mclmcr.h"
#include "matrix.h"
#include "mclcppclass.h"
#include "libMyAdd.h"
int main() {
double a = 6;
double b = 9;
double c;
// initialize lib
if( !libMyAddInitialize()) {
std::cout << "Could not initialize libMyAdd!" << std::endl;
return -1;
}
// allocate space
mwArray mwA(1, 1, mxDOUBLE_CLASS);
mwArray mwB(1, 1, mxDOUBLE_CLASS);
mwArray mwC(1, 1, mxDOUBLE_CLASS);
// set data
mwA.SetData(&a, 1);
mwB.SetData(&b, 1);
// use function: MyAdd
MyAdd(1, mwC, mwA, mwB);
// get data
c = mwC.Get(1, 1);
printf("c is %fn", c);
// terminate the lib
libMyAddTerminate();
// terminate MCR
mclTerminateApplication();
return 0;
}
最后,结果是
Compiling...
MyAdd_test.cpp
Linking...
MyAdd_test.obj : error LNK2019: unresolved external symbol _mclTerminateApplication_proxy referenced in function _main
MyAdd_test.obj : error LNK2019: unresolved external symbol _libMyAddTerminate referenced in function _main
MyAdd_test.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl MyAdd(int,class mwArray &,class mwArray const &,class mwArray const &)" (__imp_?MyAdd@@YAXHAAVmwArray@@ABV1@1@Z) referenced in function _main
MyAdd_test.obj : error LNK2019: unresolved external symbol _libMyAddInitialize referenced in function _main
MyAdd_test.obj : error LNK2019: unresolved external symbol _mclGetMatrix referenced in function "public: __thiscall mwArray::mwArray(unsigned int,unsigned int,enum mxClassID,enum mxComplexity)" (??0mwArray@@QAE@IIW4mxClassID@@W4mxComplexity@@@Z)
MyAdd_test.obj : error LNK2019: unresolved external symbol _mclcppGetLastError referenced in function "public: static void __cdecl mwException::raise_error(void)" (?raise_error@mwException@@SAXXZ)
MyAdd_test.obj : error LNK2019: unresolved external symbol _mclcppCreateError referenced in function "public: __thiscall mwException::mwException(void)" (??0mwException@@QAE@XZ)
MyAdd_test.obj : error LNK2019: unresolved external symbol _ref_count_obj_addref referenced in function "public: __thiscall mwException::mwException(class mwException const &)" (??0mwException@@QAE@ABV0@@Z)
MyAdd_test.obj : error LNK2019: unresolved external symbol _ref_count_obj_release referenced in function "public: virtual __thiscall mwException::~mwException(void)" (??1mwException@@UAE@XZ)
MyAdd_test.obj : error LNK2019: unresolved external symbol _error_info_get_message referenced in function "public: virtual char const * __thiscall mwException::what(void)const " (?what@mwException@@UBEPBDXZ)
MyAdd_test.obj : error LNK2019: unresolved external symbol _array_ref_getV_int referenced in function "public: class mwArray __cdecl mwArray::GetPromoted(unsigned int,...)" (?GetPromoted@mwArray@@QAA?AV1@IZZ)
MyAdd_test.obj : error LNK2019: unresolved external symbol _array_ref_set_numeric_mxDouble referenced in function "public: void __thiscall mwArray::SetData(double *,unsigned int)" (?SetData@mwArray@@QAEXPANI@Z)
MyAdd_test.obj : error LNK2019: unresolved external symbol _array_ref_get_numeric_mxDouble referenced in function "public: __thiscall mwArray::operator double(void)const " (??BmwArray@@QBENXZ)
C:UsersWangYudongDocumentsVisual Studio 2008ProjectsMyAdd_CDebugMyAdd_C.exe : fatal error LNK1120: 13 unresolved externals
实际上,上面的工作是我从c++调用自定义MATLAB函数的测试。我接下来的工作是将一个MATLAB程序转换成c++,其中包含imread
, edge
, strel
等图像处理功能。我试过MATLAB编码器,但它不能转换MATLAB函数。所以我尝试了上面的方法。是转换这些函数的有效方法还是我应该使用OpenCV实现它们?
在开始之前,请确保安装了受支持的编译器。如果您在64位Windows上使用VS Express版本,则可能是Visual c++和Windows SDK。接下来,您需要通过至少运行一次这些步骤来配置MATLAB:
>> mex -setup
>> mbuild -setup
现在给出下面的简单函数:
MyAdd.m
function c = MyAdd(a,b)
c = a + b;
end
我们想用MATLAB编译器mcc
构建一个c++共享库:
>> mcc -N -W cpplib:libMyAdd -T link:lib MyAdd.m -v
这将生成两个文件,包括一个头文件、一个DLL和一个导入库:
libMyAdd.h
libMyAdd.dll
libMyAdd.lib
接下来我们创建一个c++程序来测试上面的库:
MyAdd_test.cpp
#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;
}
我们可以直接从MATLAB内部编译这个程序:
>> mbuild MyAdd_test.cpp libMyAdd.lib -v
>> !MyAdd_test
我们也可以使用Visual Studio自己编译它。我们首先创建一个本机控制台应用程序,然后按如下方式设置项目设置:
- 从菜单中选择"项目>属性"并将设置应用于"所有配置"(包括调试和发布目标)
在C/c++属性下,通过添加包含生成的头文件
libMyAdd.h
的目录以及包含MATLAB头文件的目录来设置"附加包含目录":$matlabrootexterninclude
同样在"链接器"下,设置"附加图书馆目录"。这将是与之前包含
libMyAdd.lib
的目录相同的目录,以及在我的情况下:$matlabrootexternlibwin32microsoft
然后进入"链接器>输入",在"附加依赖项"中添加以下内容:
libMyAdd.lib mclmcrrt.lib
最后在"Debugging> Environment"下,您可能希望扩展
PATH
环境变量,以包含包含生成的libMyAdd.dll
文件的目录。这样你就可以直接按F5编译,直接从vs中运行程序。PATH=%PATH%;C:pathtooutputfolder
如果你经常这样做,你可以创建一个属性表,然后可以在其他vc++项目中重用。
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 未解析的外部符号_MsiLocateComponentW@12.
- 在C++中使用 gRPC 时未解析的外部符号
- LibPrivoxy: 未解析的外部符号 __declspec(dllimport) int __stdcall Sta
- 尝试从 XamlApplication 编译 C++/WinRT 空白应用程序时,我收到未解析的外部符号 winrt_make_*
- 我收到错误LNK2001:未解析的外部符号(C++代码)
- 可视抽象类 c++(错误 LNK 2001:未解析的外部符号)
- 如何摆脱C++中未解析的外部符号"private: static char"错误?
- 当 lib 已添加到其他依赖项时,如何在 VS 中调试未解析的外部符号错误
- 仅在少数方法(静态或共享库)中解析的外部符号
- 未解析的外部符号"__declspec(dllimport)与 Spdlog c++ 库
- 函数 _main (OPENGL C++) 中引用的未解析的外部符号 ________
- 错误LNK2019未解析的外部符号"public: __thiscall SLinkList<char>::SLinkList<char>(void)"
- 使用静态 constexpr 成员的未解析外部符号
- 引入参数化构造函数后显示 LNK 2019 未解析外部符号的代码错误
- Dlib LNK2001未解析的外部符号USER_ERROR__consistent_build_configurati
- 矛盾的未解决的外部符号+未使用的库与VS2017和FFMPEG 4
- 链接器错误:切换到unicode生成给出:未解析的外部符号WinMain
- 类模板上一个特定函数的未解析外部符号
- LNK2001:未解析的外部符号public:static类std::vector