c 和c 聯合編成

2022-08-27 21:54:11 字數 3916 閱讀 7996

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...