2014-01-28 37 views
0

我想從Delphi XE 32位應用程序中調用一個簡單的Matlab例程,該應用程序已使用Matlab 2012b編譯器編譯爲名爲Test.dll的共享C庫文件。 該程序增加一個數字並返回新值。初始化matlab dll並從Delphi中調用inc函數XE

正如我從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路徑中。

誰能告訴我我做錯了什麼? 在此先感謝。

+0

您確定函數名稱中的下劃線?例如在['這個答案'](http://www.mathworks.com/matlabcentral/answers/99056-how-do-i-use-the-mclinitializeapplication-function-to-make-ac-shared-library-那個 - 不 - 使用 - )它的名字中沒有下劃線。這是來自供應商支持團隊最近的帖子。 – TLama

+0

其實,不,我不確定,雖然經常需要下劃線。我也嘗試沒有下劃線,這給了我相同的結果。我在帖子中更新了這一點。 – deColaman

+0

某些名稱裝飾方案包含下劃線。在這種情況下,依賴告訴你沒有下劃線。所以不要包含它。然後,當您這樣做時,系統會告訴您* mclInitializeApplication不能位於動態鏈接庫mclmcr.dll *中。那麼,相信這個系統。它是正確的。該DLL中沒有這樣的函數。它在不同的DLL中。 –

回答

3

據我所知,該功能實際上是在mclbase.dll中定義的。

解決鏈接後,我建議您更改導入函數的參數列表。將Delphi託管類型傳遞給非Delphi模塊是有風險的。我將宣佈這樣的:

type 
    PPAnsiChar = ^PAnsiChar; 

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

事實證明,我有幾件事情來解決:

  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.'); 

我還確保這個單元是第一個被加載的項目,因爲需要在所有其他matlab調用之前調用mclInitializeApplication一次。

+0

@David,我對此表示歉意。我總是感激我從你這樣的人那裏獲得的幫助。當我最初接受你的答案時,它似乎有效,因此我接受它作爲正確的答案。我同意安裝MCR並不直接與答案相關,而且您在參數聲明中是正確的,但是我所做的最重要的錯誤是我沒有使用mclmcrrt8_0.dll。 – deColaman

+0

@David,第2部分:正如你可以從我的聲望中猜出的,我還不太熟悉stackoverflow,所以我認爲我在回答我自己的問題時做得很對。我是否應該將您的答案留作已接受的答案,還是應該根本沒有回答我的問題?當你在開始回答自己的問題時閱讀幫助彈出窗口時,似乎我正在做正確的事情。 – deColaman

+0

回答你自己的問題絕對沒問題。但事情是,你沒有那樣做。你寫的是關於事情的很多細節,只有你能看到沒有包含在問題中。因此,它只是你感興趣的。 SO遵循相當嚴格的問題和答案政策。 –