c++,混合程式設計,dll呼叫,
filenotfoundexception異常
c#寫介面比較方便,而c++則擅長寫演算法,所以將兩者結合起來將會加快程式的開發速度,並保證程式的質量。
但c#與c++的混合程式設計有很多細節問題需要注意,下面簡要列舉一些並指出相應的解決辦法。
1. 將本機c++**(指非託管c++)編譯成乙個dll,供c#呼叫,呼叫方法為[dllimport(×××.dll)] 。
但是這裡只能從dll 匯出函式,不能匯出類(還沒有測試能否匯出變數)。
不能匯出類是因為本機c++是非託管的,與c#的語言方式不相容。也就是說,
不能將此類dll作為引用 新增到c#工程中,ide會提示不是乙個程式集。
2. 利用clr
c++(指託管c++)編寫輸出類庫,供c#使用,由於clr
c++和c#都符合cls規範,
所以兩者可以無縫整合,在乙個解決方案裡包含這兩種語言的專案。生成的dll可以匯出類。
但是clr c++與傳統c++有很大的區別,可以認為是另一種不同的語言,學習它也要話費很大的精力,
所以這種方法也有些麻煩。clr c++不相容本機c++的很多內容,但可以利用指標來操作。
3. 還有乙個專門的名稱。首先建立乙個c#專案寫介面,然後新增一 個clr c++類庫專案和乙個本機c++ dll專案。
本機c++ dll專案裡面是演算法**,可以匯出類;在clr c++類庫專案裡寫乙個類,私有成員為本機c++ 類的指標
(不能用類的例項,因為cls不支援混合型別),公共成員為本機c++ dll類中的相應功能。c#呼叫clr
c++類,
clr c++類再呼叫本機c++ 類,表示如下:
native
c++==>>managed c++==>>c#
gui如果按照上面的方法做會出現一些問題。比如本機c++檔案dllclass.h:
// 此類是從dllclass.dll 匯出的
class
dllclass_api
cdllclass ;
託管c++檔案algoclr.h:
namespace
algoclr ;}c#
檔案program.cs:
class1
cls = new
class1();
cls.function();
全部編譯成功後開始除錯,偵錯程式會停在 class1
cls = new
class1() 處,提示出現filenotfoundexception異常:
assemblyfile, evidence assemblysecurity, string args)
在microsoft.visualstudio.hostingprocess.hostproc.runusersassembly()
在system.threading.threadhelper.threadstart_context(object
state)
在system.threading.executioncontext.run(executioncontext
executioncontext, contextcallback callback, object state)
在system.threading.threadhelper.threadstart()
innerexception:
去掉class1
cls = new
class1()
這一行則不會出現問題。這是因為程式需要本機c++的dll,而它沒有找到。
在targetdir(即××\bin\debug目錄)裡沒有本機c++的dll,但是有clr
c++的dll,所以我們只需要將本
機c++的dll複製到該目錄中即可。在c#專案的「屬性」->「生成事件」的「生成後事件命令列」中輸入
copy
$(solutiondir)debug\dllclass.dll $(targetdir)
dllclass.dll
為本機c++**生成的dll。然後編譯執行,就可以看到正確的結果。附生成事件語法:
命令列編輯框
包含要為預先生成或後期生成執行的事件。
注意在執行 .bat 檔案的所有後期生成命令之前新增乙個 call 語句。例如,call c:\myfile.bat 或 call c:\myfile.bat call c:\myfile2.bat。
巨集展開編輯框,顯示要插入命令列編輯框中的巨集列表。
巨集表列出可用的巨集及其值。有關每個巨集的說明,請參見下面的「巨集」。一次只能選擇將乙個巨集插入命令列編輯框中。
插入將在巨集表中選擇的巨集插入命令列編輯框中。
可以使用以下任意巨集來指定檔案位置,或在存在多重選擇的情況下獲取輸入檔案的實際名稱。這些巨集不區分大小寫。巨集說明
$(configurationname)
當前專案配置的名稱(例如,「debug|any cpu」)。
$(outdir)
輸出檔案目錄的路徑,相對於專案目錄。這解析為「輸出目錄」屬性的值。它包括尾部的反斜槓「\」。
$(devenvdir)
visual studio 2005 的安裝目錄(定義為驅動器 + 路徑);包括尾部的反斜槓「\」。
$(platformname)
當前目標平台的名稱。例如「anycpu」。
$(projectdir)
專案的目錄(定義為驅動器 + 路徑);包括尾部的反斜槓「\」。
$(projectpath)
專案的絕對路徑名(定義為驅動器 + 路徑 + 基本名稱 + 副檔名)。
$(projectname)
專案的基本名稱。
$(projectfilename)
專案的檔名(定義為基本名稱 + 副檔名)。
$(projectext)
專案的副檔名。它在副檔名的前面包括「.」。
$(solutiondir)
解決方案的目錄(定義為驅動器 + 路徑);包括尾部的反斜槓「\」。
$(solutionpath)
解決方案的絕對路徑名(定義為驅動器 + 路徑 + 基本名稱 + 副檔名)。
$(solutionname)
解決方案的基本名稱。
$(solutionfilename)
解決方案的檔名(定義為基本名稱 + 副檔名)。
$(solutionext)
解決方案的副檔名。它在副檔名的前面包括「.」。
$(targetdir)
生成的主輸出檔案的目錄(定義為驅動器 + 路徑)。它包括尾部的反斜槓「\」。
$(targetpath)
生成的主輸出檔案的絕對路徑名(定義為驅動器 + 路徑 + 基本名稱 + 副檔名)。
$(targetname)
生成的主輸出檔案的基本名稱。
$(targetfilename)
生成的主輸出檔案的檔名(定義為基本名稱 + 副檔名)。
$(targetext)
生成的主輸出檔案的副檔名。它在副檔名的前面包括「.」。
c 與python聯合程式設計一
前段時間做過c 呼叫python程式及其深度學習模型。最近想做個介面程式,將c 和python的處理結果呈現再從c 介面上。於是採用將c 程式 包括呼叫python的模組 全部寫成dll動態庫檔案。呼叫時候發現程式找不到對應的py檔案,除錯了好幾天。發現就算引用py檔案的絕對路徑也不行。錯誤程式及其...
C 和C 混合程式設計
由於歷史原因,很多時候我們的 並不完全是使用.net寫成的。這時候和以往c 的混合程式設計就顯得相當重要了。最近碰到了這樣的問題,將方法簡要記述如下。要在c 中呼叫c 函式,大體的思路是這樣的 首先將c 函式寫成dll形式的庫,然後在c 中匯入dll中的函式進行呼叫。具體的 類似這樣 c 1int ...
C 和C 混合程式設計
由於歷史原因,很多時候我們的 並不完全是使用.net寫成的。這時候和以往c 的混合程式設計就顯得相當重要了。最近碰到了這樣的問題,將方法簡要記述如下。要在c 中呼叫c 函式,大體的思路是這樣的 首先將c 函式寫成dll形式的庫,然後在c 中匯入dll中的函式進行呼叫。具體的 類似這樣 c 1 int...