【问题标题】:initializing matlab dlls and calling an inc function from Delphi XE初始化 matlab dll 并从 Delphi XE 调用 inc 函数
【发布时间】:2014-03-27 23:42:31
【问题描述】:

我正在尝试从 Delphi XE 32 位应用程序中调用一个简单的 Matlab 例程,我已使用 Matlab 2012b 编译器将其编译为名为 Test.dll 的共享 C 库。 该例程增加一个数字并返回新值。

我从 matlab 文档中了解到,我首先需要调用 mclInitializeApplication。 我已将这个 dll 调用映射如下:

unit mclmcrWrapper;

interface

type
  TAnsiArray = TArray<AnsiString>;
  PAnsiArray = ^TAnsiArray;

  function mclInitializeApplication(A: PAnsiArray; B: Integer): Boolean; cdecl; external 'mclmcr.dll' name '_mclInitializeApplication'; 

  // Also tried, with same result:
  // All attempts made with and without underscore give the same results.
  // function mclInitializeApplication(A: PAnsiArray; B: Integer): Boolean; cdecl; external 'mclmcr.dll' name '_mclInitializeApplication'; 
  // function mclInitializeApplication(A: THandle; B: Integer): Boolean; cdecl; external 'mclmcr.dll' name '_mclInitializeApplication'; 

implementation

initialization
  mclInitializeApplication(nil, 0); //Initialize the matlab runtime
end.

根据 ddlDepends,该函数存在于 dll 中。 当我执行我的程序时,我收到以下错误消息:

---------------------------
MatlabTest.exe - Entry Point Not Found
---------------------------
The procedure entry point _mclInitializeApplication could not be located in the dynamic link library mclmcr.dll. 
---------------------------
OK   
---------------------------

所有 dll 都存在于同一个文件夹中。如果不是,我会收到无法找到 dll 本身的错误。 这本身也很奇怪,因为我的系统上安装了 Matlab 编译运行时,并且它被正确添加到 windows 路径中。

谁能告诉我我做错了什么? 提前致谢。

【问题讨论】:

  • 你确定函数名中的下划线吗?例如,this answer 的名称中没有下划线。这是供应商支持团队最近发布的帖子。
  • 实际上,不,我不确定,尽管通常需要下划线。我也尝试不使用下划线,这给了我相同的结果。我已经在帖子中更新了。
  • 一些名称装饰方案包括下划线。在这种情况下,depends 告诉您没有下划线。所以不要包括它。然后,当您这样做时,系统会告诉您 mclInitializeApplication 无法位于动态链接库 mclmcr.dll 中。好吧,相信系统。它是正确的。该DLL中没有这样的功能。它位于不同的 DLL 中。

标签: matlab delphi


【解决方案1】:

据我所知,该函数实际上是在mclbase.dll 中定义的。

解决链接后,我建议您更改导入函数的参数列表。将 Delphi 托管类型传递给非 Delphi 模块是有风险的。我会这样声明:

type
  PPAnsiChar = ^PAnsiChar;

function mclInitializeApplication(A: PPAnsiChar; B: Integer): Boolean; cdecl;
  external 'mclbase.dll';

【讨论】:

    【解决方案2】:

    原来我有几件事要解决:

    1. 正确安装 MCR。
    2. 传递 PPAnsiChar 而不是数组
    3. 调用 mclmcrrt8_0.dll 中的“_proxy”函数,而不是其他 dll 文件中的普通函数。

    现在方法声明如下:

    function DLLInit(A: PPAnsiChar; B: integer): Boolean; cdecl;
      external 'mclmcrrt8_0.dll' name 'mclInitializeApplication_proxy';
    

    在单元中我添加了以下代码(是的,我没有传递任何参数):

    initialization
    
    if not DLLInit(@MyString, 0) then
      raise Exception.Create('Could not initialize Matlab library.');
    

    我还确保这个单元是第一个加载到项目中的单元,因为 mclInitializeApplication 需要在所有其他 matlab 调用之前调用一次。

    【讨论】:

    • @David,对此我深表歉意。我总是感谢像你这样的人在 stackoverflow 上提供的帮助。当我最初接受您的答案时,它似乎正在工作,因此我接受了它作为正确答案。我同意安装 MCR 与答案没有直接关系,并且您在参数声明中是正确的,但是我犯的最重要的错误是我没有使用 mclmcrrt8_0.dll。
    • @David,第 2 部分:您可以从我的名声中猜到,我对 stackoverflow 还不太熟悉,所以我认为我在回答自己的问题时做了正确的事情。我应该将您的答案作为已接受的答案,还是根本不回答我的问题?当您开始回答自己的问题时,当我阅读帮助弹出窗口时,似乎我在做正确的事情。
    • 回答你自己的问题绝对没问题。问题是,你没有那样做。你写的是很多关于只有你才能看到的东西的细节,这些东西没有包含在问题中。因此,它只对您感兴趣。 SO 遵循相当严格的问答政策。
    • 我会尽快给你的另一个Q写一个答案
    • 大卫,我理解你的反应。这让我想到了回答你自己问题的规则是什么,你的回答确实帮助了我。我再次接受它以反映这一点。我的问题是为了正确初始化 MCR,我做错了什么。也许我的问题(也不是我的回答)并不清楚。我可以更新两者以使这一点更清楚吗?请帮我解决我的其他问题。
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    相关资源
    最近更新 更多