首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >延迟加载dll的释放方式

延迟加载dll的释放方式
EN

Stack Overflow用户
提问于 2019-01-21 09:51:50
回答 2查看 1.6K关注 0票数 6

在我正在Visual构建的一个C项目(C++ 2010 Express)中,我使用MatLab引擎允许用户提供要在项目中使用的自定义函数。问题是,这段代码还需要能够在没有安装MatLab的计算机上运行,这意味着在这种情况下所需的DLL在计算机上是不可用的。当然,只有当用户不尝试访问调用matlab引擎的代码(我已经为此提供了一个标志)时,这才会起作用。

我有3个dll是这个场景所需要的。

  • libmx.dll
  • libmex.dll
  • libeng.dll

到目前为止,我已经能够使用GetProcAddress.和LoadLibrary在运行时加载libeng.dll。另外两个DLL有点困难,除了调用MatLab引擎的C代码之外,代码还经常被编译成一个mex文件(MatLab可执行文件),以便允许用户从MatLab调用它。当编译为mex文件时,libmx.dll和libmex.dll都是由mex编译器动态链接的。这意味着使用、LoadLibrary、和并不适用于这些DLL。

现在,我只是将libmx和libmex添加到visual studio中的链接器属性中,这很好,但是对于没有安装MatLab的人来说是不可能的。

我已经尝试过使用delayLoad,如果我在Debug模式下编译,这是可行的,但是在发布模式下编译时会出现这个构建错误。

代码语言:javascript
复制
1>C:\Program Files (x86)\MATLAB\R2012a\bin\win32\libmx.dll : fatal error LNK1107: invalid or corrupt file: cannot read at 0x2B8

如果使用DLL的代码部分未被访问,是否有一种方法可以完全跳过查找/加载这些DLL?

这是链接器的命令行:

代码语言:javascript
复制
/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 
EN

Stack Overflow用户

回答已采纳

发布于 2019-01-29 09:15:49

我越多地思考这个问题,它就越像XY问题

1. X(在没有MATLAB库的机器上运行MEX文件)

根据[MathWorks]:运行从其他人收到的MEX文件 (侧重点,是我的):

平台上,安装用于创建MEX文件的C++编译器运行时库。 ..。 MEX文件是一个动态链接的子程序,MATLAB解释器在调用该函数时加载并执行该子程序。动态链接意味着当您调用该函数时,程序将查找依赖库。MEX文件使用MATLAB运行时库和特定于语言的库.MEX文件也可能使用专门的运行时库。这些库的代码不包含在MEX文件中;当您运行MEX文件时,库必须出现在您的计算机上。

[MathWorks]:MATLAB包含下载多个版本的链接(根据您的路径--根据您的路径,将是installer.exe),它们是免费的(我安装了其中的3个版本来测试这个场景),并且声明:

运行编译好的MATLAB应用程序或组件而不安装MATLAB。

因此,很明显(对我来说),无论谁想使用该文件,都应该安装MCR。

2. Y(使用_Delay加载的DLL_s)

VStudio支持此特性([MS.Docs]:支持延迟加载DLL的链接器)已有相当一段时间了。

从未使用过MEX文件,也没有完整的问题规范,但是在没有MATLAB .dll_s的情况下允许一个这样的文件运行,在我看来并不像是一个好的设计(这意味着它还包含其他东西--在我看来,这些东西应该分开放置)。唯一有意义的情况是,_MEX文件将是一个.exe (不知道这是可能的还是愚蠢的事情),并且它将有一些--help等效(这将是很好的(但不是)来在没有..dll的环境中运行)。

但这也可以通过其他方法解决(例如,自述文件)

3.最终问题

考虑到问题中存在/是否存在多个(逻辑)错误:

  • _.dll_s传递给链接器
  • 位于bin dir中的.lib文件
  • 最新的路径(extern/lib/lib 64 /microsoft)包含64位.lib_s,而链接器是为_32位输出设置的
  • [MS.Docs]:链接器工具错误LNK1107,非常清楚(作为问题中的错误消息)

我只能得出结论,对于发行版,"C:\Program (x86)\MATLAB\R2012a\bin\win32\libmx.__dll被错误地输入链接器(而不是相应的.lib)。

我和MEX一起玩了一会儿

code.c

代码语言:javascript
复制
#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;
}

Notes

  • 我使用fprintf是因为mex.h中有一行: #定义printf mexPrintf
  • 不知道从libmx.dll中使用什么函数,强制直接添加它(不仅仅是libmex.dll的一个依赖项)
  • 我能够测试调试发行版中的延迟加载DLL特性(当没有传递arg时,程序运行时没有将MEX .dll_s添加到%PATH%)。 的确,在运行时,我违反了_Access,但这是一个完全不同的问题
  • 不用说,将任何.dll_s添加到"_Linker -> Input ->附加依赖项“时,都会触发完全相同的错误

最后,我想提到的是,MCR R2012a (以及其他一些在它发布后发布的)是用VStudio 9.0 (2008)构建的,使用VStudio 10.0 (2010)构建您的程序将导致在加载进程时同时使用CRT Lib_s,而且在某些情况下可能会引发一些错误(特别是因为_VStudio 9.0是作为程序集出现的)。

这适用于libmx.dll和libmex.dll,但不适用于libeng.dll。

票数 2
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54287308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档