C#呼叫C(C++)dll示例教程,包含dll找不到函式入口的解決辦法,包含C#dll呼叫方式不對出錯的解決辦法
本篇文章為了熟悉在C#環境下如何呼叫C(C++)寫的dll。
【轉帖註明出處】
一、首選建立一個C的DLL工程,生產dll檔案用來備用,步驟如下:
1、VS2010建立C++專案內選擇Win32的應用程式,名稱為CreateCDll,在應用程式設定介面內選擇DLL,如下圖:
2、在上圖中在附件選項內選擇【匯出符號】點選完成,便生成了C++的dll工程,如下圖
可以看到選擇了匯出符號的好處是工程自動幫我們建立了CREATECDLL_API的巨集,這個巨集是什麼呢,就是我們要匯出到DLL用的關鍵字可以按F12看CREATECDLL_API的原定義:
// 下列 ifdef 塊是建立使從 DLL 匯出更簡單的 // 巨集的標準方法。此 DLL 中的所有檔案都是用命令列上定義的 CREATECDLL_EXPORTS // 符號編譯的。在使用此 DLL 的 // 任何其他專案上不應定義此符號。這樣,原始檔中包含此檔案的任何其他專案都會將 // CREATECDLL_API 函式視為是從 DLL 匯入的,而此 DLL 則將用此巨集定義的 // 符號視為是被匯出的。 #ifdef CREATECDLL_EXPORTS #define CREATECDLL_API __declspec(dllexport) #else #define CREATECDLL_API __declspec(dllimport) #endif
上圖中原始檔內有三個檔案,第一個CreateCDll.cpp就是我們要寫的DLL介面函式原始檔(工程自動幫我們建立了三個範例一個變數一個函式一個類,為了簡單我們可以刪除這三段程式碼),dllmain.cpp類似於dll的main入口,stdafx.cpp就不做介紹了,好了我們開始在CreaeCDll.cpp內新增我們的介面函式,為了測試我們簡單的寫兩個函式,一個是求兩個數的和函式,第二個是比較兩個數的大小,並輸出最大值,好到此原始碼如下:
3、OK到此我們兩個介面已經寫好,我們把工程編譯一下,可以看到在工程的Debug目錄下已經生產了DLL和LIB檔案,如下圖:// CreateCDll.cpp : 定義 DLL 應用程式的匯出函式。 // #include "stdafx.h" #include "CreateCDll.h" // 求和 CREATECDLL_API int fnAdd(int num1,int num2) { return num1 + num2; } // 求最大值 CREATECDLL_API int fnMax(int num1,int num2) { return (num1 > num2)?num1:num2; }
4、好了第三步我們已經生產了DLL,下面我們要建立C#的工程來呼叫剛生成的DLL,我們建立一個C#視窗應用程式名稱為ImportCDll,儲存,新增如下介面:
5、把剛生成的dll檔案拷貝到C#工程的DEBUG目錄下,然後在C#內完成如下程式碼:
6、如上程式碼已經完成相應操作參見程式碼內註釋,需要注意的是需要新增:using System.Runtime.InteropServices;引用才能使用dll,好了編譯執行,當我們點選求和或者最大值的時候發現報錯了如下圖:using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace ImportCDll { public partial class Form1 : Form { // 匯入求和dll內函式介面 [DllImport("CreateCDll.dll",EntryPoint="fnAdd")] private static extern int fnAdd(int num1, int num2); // 匯入求最大值dll內函式介面 [DllImport("CreateCDll.dll", EntryPoint = "fnMax")] private static extern int fnMax(int num1, int num2); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } // 求和按鈕事件 private void button1_Click(object sender, EventArgs e) { textBox3.Text = string.Format("{0}",fnAdd(Convert.ToInt32(textBox1.Text),Convert.ToInt32(textBox2.Text))); } // 求最大值按鈕事件 private void button2_Click(object sender, EventArgs e) { textBox4.Text = string.Format("{0}", fnMax(Convert.ToInt32(textBox1.Text), Convert.ToInt32(textBox2.Text))); } } }
提示找不到函式入口???怎麼回事很納悶!!!為了確認是否dll內真的沒有我們兩個函式的入口,我們使用PE Explorer來開啟我們的CreateCDll.dll檔案檢視裡面的函式入口名稱,發現如下圖:
可以發現我們函式名字被改變了分別變成了:[email protected]@[email protected](對應fnAdd)和[email protected]@[email protected](對應fnMax),怎麼回事,原來編譯器在編譯的時候會自動的在我們的函式上加上標誌字元,因此我們需要在做dll檔案的時候使用def檔案來告訴編譯器不要改變我們的介面名稱,怎麼做呢?如下。
7、如上的錯誤需要在剛才的C的dll工程內新增def檔案來告訴編譯器不要修改我們的函式介面名稱,在工程上右擊【新增】---->【新建專案】,選擇【模組定義檔案(.def)】,如下圖:
輸入mydef,點選新增,在mydef檔案下新增如下程式碼:
LIBRARY "CreateCDll"
EXPORTS
fnAdd
fnMax
LIBRARY 後面新增你的dll名稱,注意不需要加.dll;在 EXPORTS下面直接新增你的函式名稱,不需要引號見上面程式碼示例。
好了到此我們再把dll的工程編譯一下,然後用PE Explorer看一下編譯好的dll的函式名稱,發現如下:
名稱已經正確好,OK再次拷貝到我們C#工程的debug目錄下,再次編譯,執行。
8、執行重新編譯,再次點選求和或者最大值按鈕,又報錯了…………,報錯介面如下:
經過百度-google了一下,發現在dll呼叫的時候需要把【CallingConvention】的呼叫方式值修改為【CallingConvention.Cdecl】,預設好像是採用【StdCall】的方式;經修改程式碼如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ImportCDll
{
public partial class Form1 : Form
{
// 匯入求和dll內函式介面
[DllImport("CreateCDll.dll", EntryPoint = "fnAdd", CallingConvention = CallingConvention.Cdecl)]
private static extern int fnAdd(int num1, int num2);
// 匯入求最大值dll內函式介面
[DllImport("CreateCDll.dll", EntryPoint = "fnMax", CallingConvention = CallingConvention.Cdecl)]
private static extern int fnMax(int num1, int num2);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
// 求和按鈕事件
private void button1_Click(object sender, EventArgs e)
{
textBox3.Text = string.Format("{0}", fnAdd(Convert.ToInt32(textBox1.Text), Convert.ToInt32(textBox2.Text)));
}
// 求最大值按鈕事件
private void button2_Click(object sender, EventArgs e)
{
textBox4.Text = string.Format("{0}", fnMax(Convert.ToInt32(textBox1.Text), Convert.ToInt32(textBox2.Text)));
}
}
}
9、再次編譯執行,OK了效果如下:
OK,到此結束,希望對新手有幫助。
相關推薦
Java專案讀取配置檔案時,FileNotFoundException 系統找不到指定的檔案,System.getProperty("user.dir")的理解
唉,讀取個檔案,也就是在專案裡面去獲得配置檔案的目錄,然後,變成檔案,有事沒事,總是出個 FileNotFoundException 系統找不到指定的檔案,氣死人啦。 還有就是:System.getProperty("user.dir"),都說獲得的是“工作目錄”,有老鐵
C#呼叫C(C++)dll示例教程,包含dll找不到函式入口的解決辦法,包含C#dll呼叫方式不對出錯的解決辦法
本篇文章為了熟悉在C#環境下如何呼叫C(C++)寫的dll。 【轉帖註明出處】 一、首選建立一個C的DLL工程,生產dll檔案用來備用,步驟如下: 1、VS2010建立C++專案內選擇Win32的應用程式,名稱為CreateCDll,在應用程式設定介面內選擇DLL,如下圖:
在c#中引用Microsoft.SqlServer.Types後,系統執行報"未能載入 SqlServerSpatial140.dll,找不到指定的模組,(異常來自......)的解決方法
1.在資源管理器中檢視C:\Windows\System32或者C:\Windows\SysWOW64下有沒有SqlServerSpatialXXX.dll的檔案,如果沒有,在網上下載後,把檔案重新命名為報錯的dll檔名,將其放入此目錄下 2.如果有,如下圖,我將原本的130改為140,程式便不
安裝xampp時提示找不到文件“-n”,提示沒有安裝Microsoft Visual C++ 2008 Redistributable Package (x86)
pac sdn .exe tro setup net sof edi microsoft ①安裝xampp時提示找不到文件“-n”; ②提示沒有安裝Microsoft Visual C++ 2008 Redistributable Package (x86)。 解決方法如下
c# 無法載入DLL“xxxx”:找不到指定的模組(異常來自HRESULT:0X8007007E)的一個解決方法
以前的一個c#專案,今天執行的時候突然發現呼叫DLL時出現了下面的錯誤。 心中很詫異,明明以前能用的,今天怎麼報錯了。程式碼沒有修改,也不存在DLL路徑錯誤的問題。 後來看到有網友說用 depend
python setup.py install 報錯:error: [WinError 3] 系統找不到指定的路徑。: 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\PlatformSDK\\lib
Outline 在通過 setup.py 安裝python模組時,遇到了以下報錯: # 執行 python setup.py install # 報錯: error: [WinError 3] 系統找不到指定的路徑。: 'C:\\Program Files (x86)\\Microsof
vs程式執行時報錯"未能載入 SqlServerSpatialxxx.dll,找不到指定的模組,(異常來自......)"的解決方法
報錯原因: 因為程式中引用了Microsoft.SqlServer.Types程式集,正常情況下程式會去c:\windows\system32或者c:\windows\syswow64目錄中尋找,所以找不到。 其實你引用時已經在bin\debug\SqlServerTypes資料夾下生成了報
【小松教你手遊開發】【unity實用技能】u3d 當你發現一個函式被呼叫,但是完全找不到是誰呼叫的時候
一般有可能是通過函式名作為字串呼叫,但是這種在除錯時也是能跟蹤到 而如果連除錯都跟蹤不到的時候,看看是不是動畫效果。 如果是的話可能是在那個特效中呼叫。 這樣的話除錯也跟蹤不到。 這種時候要找的話要定位到對應的GameObject上,開啟Animation,檢視 長這
[記錄點滴]授人以漁,從Tensorflow找不到dll擴充套件到如何排查問題
# [記錄點滴]授人以漁,從Tensorflow找不到dll擴充套件到如何排查問題 [toc] ## 0x00 摘要 本文將通過一個經典的 “tensorflow找不到dll” 問題來入手,給大家一個如何找到缺失dll的辦法,進而再分享一個windows上排查問題的好工具(因為大多開發者在windows
【Python】selenium調用IE11瀏覽器,報錯“找不到元素”NoSuchWindowException: Message:Unable to find element on closed window
conn ont csdn creates logs 註冊 target get 意思 當編寫自動化腳本,定位瀏覽器元素時,報如下錯誤: 代碼: >>> # coding=utf-8 >>> from selenium import w
12306火車票訂票失敗!您的身份信息未經核驗,一般人是不能訂票的,我訂了,可是沒成功。。。
ext con efault jsb fill ast edit 技術 post 12306火車票訂票失敗!您的身份信息未經核驗。一般人是不能訂票的,我訂了,可是沒成功。。。 上圖哈,未經核驗能能夠訂票,只是出票失敗了。看來12306不是吃幹飯的
web頁面找不到資源文件,報404,但是資源文件存在且路徑沒錯
環境搭建 思維 邏輯 資源 存在 lan 開始 details tails 如題 , 今天遇到這個問題,maven項目導入本地myeclipse,正常跑起來之後,在web端存在部分頁面資源加載不進來。 但是項目資源確實存在,一開始以為是myeclipse開發環境搭建錯誤導
各類無次數限制的免費API接口,再也不怕找不到免費API了
p地址 歸屬地查詢 指數 騰訊 tps developer 馬化騰 soj yun 各類無次數限制的免費API接口整理,主要是聚合數據上和API Store上的一些,還有一些其他的。聚合數據提供30大類,160種以上基礎數據API服務,國內最大的基礎數據API服務,下面就羅
前端經驗之談(在項目中經常使用,但是有時候想不起來的一些東西,待完善,想起一個加一個)
經驗之談 letter 節點 ont 前端 val 隱藏元素 utl ade css: align-items: center; 該樣式配合display: flex;可以使子元素垂直居中 justify-content: center; 該樣式配合display
Linux下Java運行.class文件,報錯找不到或無法加載主類
code 運行 pro jar 更改 class ssp linux lib classpath配置的錯誤,所以找不到.class文件。 原先的etc/profile中的classpath配置 export CLASSPATH=$JAVA_HOME/lib/tools.j
知道這4個隱藏資源網站的人非常少,難怪總是找不到資源
3-0 圖片 搜索 網易雲音樂 分享 qq音樂 需要 ade -c 現在的互聯網是開放的,我們可以通過網絡下載到很多自己需要的東西,但是有些網站因為不夠知名而被忽視,但是裏面的資源還是很不錯的。 今天小編就來跟大家分享幾個隱藏的資源網站: Aio search 國外的一個B
Django admin後臺管理無樣式,報錯找不到靜態檔案
python+django+uwsgi 建立超級使用者進入admin後臺管理時,發現沒有樣式,報錯找不到靜態檔案(報錯如下) Not Found: /static/admin/css/dashboard.css Not Found: /static/admin/css/base.c
在IntelliJ IDEA中,註解@Slf4j找不到log
轉載:https://blog.csdn.net/qq_26346457/article/details/78736373 @Test public void test2(){ &nbs
Linux下Java執行.class檔案,報錯找不到或無法載入主類
classpath配置的錯誤,所以找不到.class檔案。 原先的etc/profile中的classpath配置 export CLASSPATH=$JAVA_HOME/lib/tools.jar 更改後的: export CLASSPATH=.:$JAVA_HOME
SQL語句中,為什麼where子句不能使用列別名,而order by卻可以?
當select的表示式很長時,我們經常會用as子句為該表示式指定別名,然而卻發現無法在Where條件中直接使用該別名作為判斷條件. 例如下面的SQL語句: select id, (c1 + c2) as s from t1 where s > 100 執行會