轉二
使用C#生成dll文件並調用
一、創建dll文件: 例如生成一個md5編碼判斷狀態的文件,即,輸入一個字符串(string A)和一個32位md5編碼(string B),判斷此字符串A對應的32位md5編碼是否與B相等,如果相等返回true,否則返回false。 打開VS 2005,“文件”--》“新建”--“項目”,選擇“Windows 控件庫”,命名后點擊“確定”,在“UserControl1.cs”中輸入以下代碼: using System; using System.Text; namespace md5 for (int i = 0; i < 16; i++) return sb.ToString().ToUpper(); #region 核對md5編碼是否一致:CheckMd5String() int result = string.Compare(md5.Program.GetMd5Str32(str1), md5DbString, true); 修改“UserControl1.Designer.cs”中的命名空間為“md5”,方法為“Program”,即可生成dll文件。 在...\bin\Debug文件假下,可以找到相應的dll文件。 二、部署dll流程: 首先把dll文件放到應用程序...\bin\Debug\下; 測試應用程序代碼,如下:Form1.cs using System;
namespace WindowsApplication1 private void button1_Click(object sender, EventArgs e) textBox3.Text = md5.Program.GetMd5Str32(str1); private void button2_Click(object sender, EventArgs e)
三、注意點: 1、在C#應用程序開發過程中,加載dll文件時,報錯“未能加載文件或程序集“md5, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一個依賴項。系統找不到指定的文件。”,請指點一下是什么原因? |
-------------------------------------------------------------------------------------------------------------------------------
關於 Asp.NET 調用C#生成的DLL問題
生成以后,有2個文件:/bin/debug/xxx.dll和xxx.pdb, 這2個文件有什么用?
我把2個文件copy到 asp.Net /bin/下
然后引用該dll,
.cs中使用 using xxx;成功
可是在創建新類的時候:yyy myxx=new yyy();//xxx.yyy()
已經可以看到 myxx的屬性和方法了(myxx.有提示),可是卻報以下錯,請教各位!
發生類型為 System.StackOverflowException 的異常。
說明: 執行當前 Web 請求期間,出現未處理的異常。
請檢查堆棧跟蹤信息,以了解有關該錯誤以及代碼中導致錯誤的出處的詳細信息。
異常詳細信息: System.StackOverflowException:發生類型為 System.StackOverflowException 的異常。
源錯誤:
執行當前 Web 請求期間生成了未處理的異常。可以使用下面的異常堆棧跟蹤信息確定有關異常原因和發生位置的信息。
堆棧跟蹤:
[StackOverflowException: 發生類型為 System.StackOverflowException 的異常。]
--------------------------------------------------------------------------------
版本信息: Microsoft .NET 框架版本:1.0.3705.288; ASP.NET 版本:1.0.3705.288
--
dll文件是你服務器端腳本編譯后生成的組件,也就是說一但編譯成dll后,
軟件發行后,你對應頁面的服務器端腳本文件.aspx.cs就不需要發布了,
因為代碼已經封裝在工程名.dll文件里了.而.pdb文件據我理解,可能是帶上了一些資源類的文件吧,
所以文件要比相應的dll文件大,至於你說的這個問題,我沒碰到過,幫不了你
--
我是在類庫項目中生成的DLL,然后在asp.net項目中調用。
btw:我剛才測試了一個新的C#生成的DLL,沒有引入其它dll,
一樣的操作不會報錯,樓上的那個dll引用了其它dll,請問和這個有關嗎?
----
我只能說有可能
---
那這樣說你自己也發現了答案呢,把間接引用到的DLL也加入到工程中試試看
----
比如有一個別人寫的aa.dll,在我的類庫中引用了,還需要在asp.net工程中引用嗎?
----
一般StackOverflowException是由於無限循環等原因引起的,看看你的代碼會不會有這個問題。
----
比如有一個別人寫的aa.dll,在我的類庫中引用了,還需要在asp.net工程中引用嗎?
我猜想還應該用的吧,你自己做個小的程序來試試看。
我覺得你的類庫雖然引用了那個DLL,但並沒有把那個DLL也編譯進你自己的DLL中(有沒有靜態編譯?)
----
靜態編譯?不是很明白我是通過vs.net生成的
----
debug會生成兩個文件
pdf負責調試工作
發布的時候應該使用realease版本
-------------------------------------------------------------------------------------------------------------------------------
c#生成DLL文件,內部函數的問題
用C#編寫一組處理XML文檔的代碼,由於要求生成DLL文件,並由外部的其他工具訪問動態庫中的文件,
但是用Dependency Walker檢測我生成的這個DLL文件沒有顯示任何的函數,以前沒做過這方面的東西,求教了
代碼如下:
using System;
using System.IO;
using System.Xml;
public class Sample
{
public static void Main()
{
DeleteArg();
}
static void DeleteArg()
{
XmlDocument doc = new XmlDocument();
doc.Load(@"c:\\data1.xml");
XmlNode root = doc.DocumentElement;
XmlNode Node1;
XmlNodeList nodeList = doc.SelectSingleNode("/Entity/Columns").ChildNodes;
foreach (XmlNode xn in nodeList)
{
XmlElement xe = (XmlElement)xn;
if (xe.GetAttribute("Name") == "SysModuleID")
{
xe.RemoveAll();
//xe.RemoveAttribute("Name");//刪除Name屬性
}
}
doc.Save("c:\\data1.xml");//保存這個文檔到文件中
}
}
以上代碼實現刪除XML文件中某一節點的功能,如何在生成DLL后能夠使用檢測工具檢測出DeleteArg函數,
使用Dependency Walker沒檢測出該函數是不是以為着這個動態庫文件不能被調用.
----
因為.net的程序不是這樣把函數放在導出表的, 我記得.net做的dll只導出了一個_CorDllMain的方法,
所以用Dependency Walker是看不出來的. 如果你想看.net做的dll導出了什么內容,可以用反射查看元數據
----
生成這個DLL庫文件,是想要別的工具運行這個動態庫文件,實現DELETEARG()這個函數的功能
----
可以的
----
你上面的代碼不是生成DLL的,而是一個控制台應用程序.
要想創建動態庫(DLL),在新建項目窗口中選擇"類庫", 默認的代碼是這樣的:
using System;
using System.Collections.Generic;
using System.Text;
namespace ClassLibrary2
{
public class Class1
{
}
}
// 然后添加你的代碼.最后代碼如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace ClassLibrary2
{
public class Class1
{
public void DeleteArg()
{
XmlDocument doc = new XmlDocument();
doc.Load(@"c:\\data1.xml");
XmlNode root = doc.DocumentElement;
XmlNode Node1;
XmlNodeList nodeList = doc.SelectSingleNode("/Entity/Columns").ChildNodes;
foreach (XmlNode xn in nodeList)
{
XmlElement xe = (XmlElement)xn;
if (xe.GetAttribute("Name") == "SysModuleID")
{
xe.RemoveAll();
//xe.RemoveAttribute("Name");//刪除Name屬性
}
}
doc.Save("c:\\data1.xml");//保存這個文檔到文件中
}
}
}
最后編譯一下就可以,
在Debug文件夾下回產生一個dll文件,最后在需要的工程里,將這個dll文件引進進去就可以用.
例如:
using ClassLibrary2;
......
Class1 class = new Class1();
class.DeleteArg();
二、命令方法
使用csc命令將.cs文件編譯成.dll的過程
很多時候,我們需要將.cs文件單獨編譯成.dll文件, 操作如下:
打開命令窗口->輸入cmd到控制台->cd C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322
轉到vs.net安裝的該目錄下->執行csc命令csc /target:library File.cs->在該目錄下產生一個對應名字的.dll文件(前提:把.cs文件放到C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322目錄下)
csc /target:library /out:myDll.DLL myDll.cs生成組件myDll.dll,該組件會在工程文件的bin\debug目錄里,文件擴展名是dll。
csc命令的方式很多,請參考以下
譯 File.cs 以產生 File.exe
csc File.cs 編譯 File.cs 以產生 File.dll
csc /target:library File.cs 編譯 File.cs 並創建 My.exe
csc /out:My.exe File.cs 通過使用優化和定義 DEBUG 符號,編譯當前目錄中所有的 C# 文件。輸出為 File2.exe
csc /define:DEBUG /optimize /out:File2.exe *.cs 編譯當前目錄中所有的 C# 文件,以產生 File2.dll 的調試版本。不顯示任何徽標和警告
csc /target:library /out:File2.dll /warn:0 /nologo /debug *.cs 將當前目錄中所有的 C# 文件編譯為 Something.xyz(一個 DLL)
csc /target:library /out:Something.xyz *.cs 編譯 File.cs 以產生 File.dll
csc /target:library File.cs這個就是我們使用最多的一個命令,其實可以簡單的寫成csc /t:library File.cs,另外的一個寫法是 csc /out:mycodebehind.dll /t:library mycodebehind.cs,這個可以自己指定輸出的文件名。
csc /out:mycodebehind.dll /t:library mycodebehind.cs mycodebehind2.cs,這個的作用是把兩個cs文件裝到一個.dll文件里
csc不是內部或外部命令,也不是可運行的程序解決方法
針對VisualStudio2005
1:右鍵點擊"我的電腦"--"屬性"--"高級"--"環境變量"--"系統變量"
將PATH中加上路徑:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\
2:直接在dos環境的cs相應文件夾目錄執行
Path=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\
3:VisualStudio2005命令提示
開始--》程序---》Microsoft Visual Studio2005---->Visual Studio Tools--->VisualStudio2005命令提示
把cs文件copy到C:\Program Files\Microsoft Visual Studio 8\VC\
4:C:\autoexec.bat
加入:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\
vs2008 下
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ 里的CSC.EXE 是2.0版本
編譯的.cs文件如果帶using System.Linq;編譯通不過,如果不用LINQ語法刪除using System.Linq;即可,否則 調用C:\WINDOWS\Microsoft.NET\Framework\v3.5里的CSC.EXE
同一SLN下 里面 class 直接訪問類庫。
封裝到DLL。 導入DLL 添加using namespace 工有才能訪問。
一、 動態鏈接庫
什么是動態鏈接庫?DLL三個字母對於你來說一定很熟悉吧,它是Dynamic Link Library 的縮寫形式,動態鏈接庫 (DLL) 是作為共享函數庫的可執行文件。動態鏈接提供了一種方法,使進程可以調用不屬於其可執行代碼的函數。函數的可執行代碼位於一個 DLL 中,該 DLL 包含一個或多個已被編譯、鏈接並與使用它們的進程分開存儲的函數。DLL 還有助於共享數據和資源。多個應用程序可同時訪問內存中單個 DLL 副本的內容。
和大多數程序員一樣,你一定很使用過DLL吧。也曾感受到它的帶給你程序設計和編碼上的好錯吧今天我想和大家探討一個主題:如何在C#創建和調用DLL(動態鏈接庫), 其實在很大意義上而講,DLL讓我更靈活的組織編寫我們的應用程序,作為軟件設計者,可一個根據它來達到很高的代碼重用效果。下面我來介紹一下在C#中如何創建和調用DLL。
二、准備工作
我們需要對我們接下來要做的事情做個簡單的介紹,在本文我們將利用C#語言創建一個名為 MyDLL.DLL的動態鏈接庫,在這個動態鏈接庫文件中我們將提供兩個功能一個是對兩個參數交換他們的值,另一個功能是求兩個參數的最大公約數。然后創建一個應用程序使用這個DLL。運行並輸出結果。
三、創建DLL
讓我們創建以下三個C#代碼文件:
1、 MySwap.cs
view plaincopy to clipboardprint?
using System;
namespace MyMethods
{
public class SwapClass
{
public static bool Swap(ref long i,ref long j)
{
i = i+j;
j = i-j;
i = i-j;
return true;
}
}
}
using System;
namespace MyMethods
{
public class SwapClass
{
public static bool Swap(ref long i,ref long j)
{
i = i+j;
j = i-j;
i = i-j;
return true;
}
}
}
2、MyMaxCD.cs
view plaincopy to clipboardprint?
using System;
namespace MyMethods
{
public class MaxCDClass
{
public static long MaxCD(long i, long j)
{
long a,b,temp;
if(i>j)
{
a = i;
b = j;
}
else
{
b = i;
a = j;
}
temp = a % b;
while(temp!=0)
{
a = b;
b = temp;
temp = a % b;
}
return b;
}
}
}
using System;
namespace MyMethods
{
public class MaxCDClass
{
public static long MaxCD(long i, long j)
{
long a,b,temp;
if(i>j)
{
a = i;
b = j;
}
else
{
b = i;
a = j;
}
temp = a % b;
while(temp!=0)
{
a = b;
b = temp;
temp = a % b;
}
return b;
}
}
}
需要注意的是:我們在制作這兩個文件的時候可以用Visual Studio.NET或者其他的文本編輯器,就算是記事本也可以。這兩個文件雖然不在同一個文件里面,但是他們是屬於同一個namespace(名稱空間)這對以后我們使用這兩個方法提供了方便。當然他們也可以屬於不同的名稱空間,這是完全可以的,但只是在我們應用他們的時候就需要引用兩個不同的名稱空間,所以作者建議還是寫在一個名稱空間下面比較好。
接下來的任務是把這兩個cs文件變成我們需要的DLL文件。方法是這樣的:在安裝了Microsoft.NET Framework的操作系統上,我們可以在Windows所在目錄下找到Microsoft.NET目錄。在這個目錄下面提供了C#的編譯器,CSC.EXE運行:csc /target:library /out:MyDLL.DLL MySwap.cs MyMaxCD.cs,完成后可在本目錄下面找到我們剛才生成的MyDLL.DLL文件/target:library 編譯器選項通知編譯器輸出 DLL 文件而不是 EXE 文件。后跟文件名的 /out 編譯器選項用於指定 DLL 文件名。如果/out后面不跟文件名編譯器使用第一個文件 (MySwap.cs) 作為 DLL 文件名。生成的文件為MySwap.DLL文件。
OK!我們創建動態鏈接庫文件的任務完成了,現在是我們享受勞動成果的時候了,下面我將介紹如何使用我們所創建的動態鏈接庫文件。 四、使用DLL 我們簡單寫一個小程序來測試一下我們剛才寫的兩個方法是否正確,好吧,跟我來:
MyClient.cs
view plaincopy to clipboardprint?
using System;
using MyMethods; //這里我們引用剛才定義的名稱空間,如果剛才的兩個文件我們寫在兩個不同的名稱空間
class MyClient
{
public static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: MyClient <num1> <num2>");
return;
}
long num1 = long.Parse(args[0]);
long num2 = long.Parse(args[1]);
SwapClass.Swap(ref num1,ref num2);
// 請注意,文件開頭的 using 指令使您得以在編譯時使用未限定的類名來引用 DLL 方法
Console.WriteLine("The result of swap is num1 = {0} and num2 ={1}",num1, num2);
long maxcd = MaxCDClass.MaxCD(num1,num2);
Console.WriteLine("The MaxCD of {0} and {1} is {2}",num1, num2, maxcd);
}
}
using System;
using MyMethods; //這里我們引用剛才定義的名稱空間,如果剛才的兩個文件我們寫在兩個不同的名稱空間
class MyClient
{
public static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: MyClient <num1> <num2>");
return;
}
long num1 = long.Parse(args[0]);
long num2 = long.Parse(args[1]);
SwapClass.Swap(ref num1,ref num2);
// 請注意,文件開頭的 using 指令使您得以在編譯時使用未限定的類名來引用 DLL 方法
Console.WriteLine("The result of swap is num1 = {0} and num2 ={1}",num1, num2);
long maxcd = MaxCDClass.MaxCD(num1,num2);
Console.WriteLine("The MaxCD of {0} and {1} is {2}",num1, num2, maxcd);
}
}
若要生成可執行文件 MyClient.exe,請使用以下命令行:
csc /out:MyClient.exe /reference:MyLibrary.DLL MyClient.cs
/out 編譯器選項通知編譯器輸出 EXE 文件並且指定輸出文件名 (MyClient.exe)。/reference 編譯器選項指定該程序所引用的 DLL 文件。
五、執行
若要運行程序,請輸入 EXE 文件的名稱,文件名的后面跟兩個數字,例如:MyClient 123 456
六、輸出
The result of swap is num1 = 456 and num2 = 123
The MaxCD of 456 and 123 is 3
七、小結
動態鏈接具有下列優點:
1、節省內存和減少交換操作。很多進程可以同時使用一個 DLL,在內存中共享該 DLL 的一個副本。相反,對於每個用靜態鏈接庫生成的應用程序,Windows 必須在內存中加載庫代碼的一個副本。
2、節省磁盤空間。許多應用程序可在磁盤上共享 DLL 的一個副本。相反,每個用靜態鏈接庫生成的應用程序均具有作為單獨的副本鏈接到其可執行圖像中的庫代碼。 3、升級到 DLL 更為容易。DLL 中的函數更改時,只要函數的參數和返回值沒有更改,就不需重新編譯或重新鏈接使用它們的應用程序。相反,靜態鏈接的對象代碼要求在函數更改時重新鏈接應用程序。
4、提供售后支持。例如,可修改顯示器驅動程序 DLL 以支持當初交付應用程序時不可用的顯示器。
5、支持多語言程序。只要程序遵循函數的調用約定,用不同編程語言編寫的程序就可以調用相同的 DLL 函數。程序與 DLL 函數在下列方面必須是兼容的:函數期望其參數被推送到堆棧上的順序,是函數還是應用程序負責清理堆棧,以及寄存器中是否傳遞了任何參數。
6、提供了擴展 MFC 庫類的機制。可以從現有 MFC 類派生類,並將它們放到 MFC 擴展 DLL 中供 MFC 應用程序使用。
7、使國際版本的創建輕松完成。通過將資源放到 DLL 中,創建應用程序的國際版本變得容易得多。可將用於應用程序的每個語言版本的字符串放到單獨的 DLL 資源文件中,並使不同的語言版本加載合適的資源。
使用 DLL 的一個潛在缺點是應用程序不是獨立的;它取決於是否存在單獨的 DLL 模塊