转二
使用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 模块