在我在Visual Studio(C ++ 2010 Express)中构建的C项目中,我使用MatLab引擎来允许用户提供要在项目中使用的自定义函数。问题在于,此代码还需要能够在未安装MatLab的计算机上运行,这意味着在这种情况下,所需的DLL将在计算机上不可用。当然,这仅在用户不尝试访问调用matlab引擎的代码段时才有效(我为此提供了一个标志)。
在这种情况下,我有3个dll。
到目前为止,我已经可以使用 LoadLibrary 和 GetProcAddress 在运行时加载libeng.dll。 但是,除了调用MatLab引擎的C代码之外,其他两个DLL都较难一些,该代码通常还被编译为mex文件(MatLab可执行文件),以允许用户从MatLab对其进行调用。当作为mex文件编译时,mex编译器会动态链接libmx.dll和libmex.dll。这意味着使用 LoadLibrary 和 GetProcAddress 不适用于这些DLL。
现在,我只是将libmx和libmex LIB添加到Visual Studio中的链接器属性中,这可以正常工作,但是对于未安装MatLab的用户来说是不可能的。
我尝试使用 delayLoad ,如果我在“调试”模式下进行编译,则此方法有效,但是在“发布”模式下进行编译时,则会出现此生成错误。
1>C:\Program Files (x86)\MATLAB\R2012a\bin\win32\libmx.dll : fatal error LNK1107: invalid or corrupt file: cannot read at 0x2B8
如果未访问使用它们的部分代码,是否有一种方法可以完全跳过查找/加载这些DLL?
这是链接器的命令行:
/OUT:"C:\Users\A.Vandenber\documents\visual studio 2010\Projects\Flash\Release\Flash.exe" /NOLOGO "C:\Program Files (x86)\MATLAB\R2012a\bin\win32\libmx.lib" "C:\Program Files (x86)\MATLAB\R2012a\bin\win32\libmex.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DELAYLOAD:"libmex.dll" /DELAYLOAD:"libmx.dll" /MANIFEST /ManifestFile:"Release\Flash.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\Users\A.Vandenber\documents\visual studio 2010\Projects\Flash\Release\Flash.pdb" /OPT:REF /OPT:ICF /PGD:"C:\Users\A.Vandenber\documents\visual studio 2010\Projects\Flash\Release\Flash.pgd" /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE
答案 0 :(得分:2)
我考虑得越多,它看起来就越像[Wikipedia]: XY problem。
根据[MathWorks]: Run MEX File You Receive from Someone Else(重点是我的):
在Windows®平台上,安装用于创建MEX文件的C ++编译器运行时库。
...
MEX文件是一个动态链接子例程,调用该函数时,MATLAB解释器将加载并执行该子例程。动态链接意味着当您调用函数时,程序将查找相关的库。 MEX文件使用MATLAB运行时库和特定于语言的库。 MEX文件可能还使用专用的运行时库。这些库的代码未包含在MEX文件中;这些文件已包含在MEX文件中。 运行MEX文件时,库必须存在于计算机中。
[MathWorks]: MATLAB Runtime包含用于下载许多版本的链接(您的-根据您的路径-将是[MathWorks]: MCR Runtime - MCR_R2012a_win32_installer.exe),这些版本免费(我安装了其中三个版本来测试这种情况),并指出:
运行编译的MATLAB应用程序或组件而无需安装MATLAB
因此,(对我而言)很明显,任何想使用该文件的人都应该安装 MCR 。
VStudio 支持此功能([MS.Docs]: Linker Support for Delay-Loaded DLLs)已有一段时间。
从未使用过 MEX 文件,也没有完整的问题说明,但是当没有 MATLAB .dll < / em>的礼物对我来说似乎不是一个好的设计(这意味着它还包含其他内容-我认为应单独放置)。唯一有意义的情况是 MEX 文件将是 .exe (不知道这是可能的还是愚蠢的事情),并且一些--help
等效项(在没有 .dll 的环境中运行会很好(但不是强制性))。
但是也可以使用其他方式(例如类似文件的 README )来解决
考虑到问题中存在/有多个(逻辑)错误:
我只能得出结论,对于发布,“ C:\ Program Files(x86)\ MATLAB \ R2012a \ bin \ win32 \ libmx。 dll < / em>“ 错误地馈送到了链接器(而不是相应的 .lib )。
我在 MEX 中玩过一点:
code.c :
#include <stdio.h>
#include <conio.h>
#include <mex.h>
int main(int argc, char **argv) {
if (argc > 1) {
fprintf(stdout, "Argument passed: mexEvalString() returns\n", mexEvalString("n = 1;"));
} else {
fprintf(stdout, "Argument NOT passed: pass...\n");
}
fprintf(stdout, "Press a key to exit...\n");
_getch();
return 0;
}
注释:
我使用了 fprintf ,因为在 mex.h 中有一行:
#define printf mexPrintf
不知道要从 libmx.dll 中使用什么功能,以强制将其直接添加(而不仅仅是 libmex.dll 的依赖项)< / p>
最后,我要提到 MCR R2012a (以及其后发布的其他一些产品)是使用 VStudio 9.0 (2008 ),并使用 VStudio 10.0(2010)构建程序,将会同时加载 CRT Lib ,并且在某些情况下可能会触发一些错误(尤其是因为 VStudio 9.0 作为程序集附带)。
这适用于 libmx.dll 和 libmex.dll ,但不适用于 libeng.dll 。
答案 1 :(得分:0)
首先,将代码移动到具有access privileges
而不是read-only
的目录中。也可以在这里查看此答案:Delay load DLL
要将dll
文件添加到Visual Studio,您可以按照以下Linking dll in Visual Studio
另一建议是将dll
放在c:\windows\system32
中。程序运行时,它将在c:\windows\system32
目录中搜索该文件。在此之前,它将搜索运行程序的目录。 Visual Studio从其项目的目录(如果没有将其放置在windows\system32
目录中,则应在其中放置提到的.dll文件)运行程序。同样,如果程序的可执行文件是从其目录中手动运行的,则该.dll文件应位于same folder where the program's executable
文件中。您将需要管理员权限才能做到这一点。