在Silverlight程序(非Out of Browser模式)中是无法直接调用DLL的,但是很多的计算或者其他应用程序的调用中我们需要用到DLL的加载。比如调用DLL来识别身份证读卡器传 输过来的信号,比如要和某Delph编写的程序数据通讯等等。本文将简单的自写一个DLL文件,然后通过调用此DLL自定义的一个GetNum函数计算传 入得两个参数之和。

        首先我们使用VS2010编写一个名为IlasLinkDll.dll的C++语言DLL文件(编写这个DLL的源码也会在本章结尾附带),其内部的关键代码如下:

 

  1. #ifdef MYLIBDLL 
  2. #define MYLIBDLL extern "C" _declspec(dllimport) 
  3. #else 
  4. #define MYLIBDLL extern "C" _declspec(dllexport) 
  5. #endif 
  6. MYLIBDLL double GetNum(double Anum,double Bnum); 
  7.  
  8. double GetNum(double Anum,double Bnum) 
  9.  
  10. return Anum+Bnum; 

        然后我们新建一个名为SLLinkDLl的Silverlight应用程序项目,在SLLinkDLl.Web项目中我们引用 IlasLinkDll.dll文件,新建一个Wservice.asmx的web服务文件。在此文件中编写以下代码且添加using System.Runtime.InteropServices;的引用:

 

  1. [WebMethod] 
  2. public string GetNumber(double A,double B) 
  3. return GetNum(A, B).ToString() ; 
  4.  
  5. /// <summary> 
  6. /// 获取到DLL的值 
  7. /// </summary> 
  8. /// <param name="Anumber">数字A</param> 
  9. /// <param name="Bnumber">数字B</param> 
  10. /// <returns></returns
  11. [DllImport("IlasLinkDll.dll", CharSet = CharSet.Ansi, EntryPoint = "GetNum", ExactSpelling = false)] 
  12. public static extern double GetNum(double Anumber, double Bnumber); 

        最后在Silverlight程序中鼠标右键点击项目名--添加服务引用--添加http://localhost:4389/Wservice.asmx地址即可。在MainPage.xaml.cs文件中写入以下关键代码即可调用WebService中的GetNumber方法,通过DLL计算两个数字之间的和,返回显示出来。

 

  1. public MainPage() 
  2. InitializeComponent(); 
  3. //创建webService代理类的对象实例 
  4. WServiceSoapClient sclient=new WServiceSoapClient(); 
  5. //调用GetNumber方法,并传递两个参数 
  6. sclient.GetNumberAsync(500,23); 
  7. sclient.GetNumberCompleted += new EventHandler<GetNumberCompletedEventArgs>(sclient_GetNumberCompleted); 
  8.  
  9.  
  10. void sclient_GetNumberCompleted(object sender, GetNumberCompletedEventArgs e) 
  11. //结果将为523 
  12. MessageBox.Show(e.Result); 

        通过上面的代码我们传入500和23两个参数。然后得到结果为523的弹出窗口。下面我们看一下加载DLL的DllImport特性的参数使用方法:

 

  1. [DllImport("IlasLinkDll.dll", CharSet = CharSet.Ansi, EntryPoint = "GetNum", ExactSpelling = false)] 
  2.  
  3.    a、CallingConvention 参数指示入口点的调用约定。如果未指定 CallingConvention,则使用默认值 CallingConvention.Winapi。 
  4.    b、CharSet 参数指示用在入口点中的字符集。如果未指定 CharSet,则使用默认值 CharSet.Auto。 
  5.    c、EntryPoint 参数给出 dll 中入口点的名称。如果未指定 EntryPoint,则使用方法本身的名称。 
  6.    d、ExactSpelling 参数指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配。如果未指定 ExactSpelling,则使用默认值 false。 
  7.    e、PreserveSig 参数指示方法的签名应当被保留还是被转换。当签名被转换时,它被转换为一个具有 HRESULT 返回值和该返回值的一个名为 retval 的附加输出参数的签名。如果未指定 PreserveSig,则使用默认值 true。 
  8.    f、SetLastError 参数指示方法是否保留 Win32"上一错误"。如果未指定 SetLastError,则使用默认值 false。 

        Tip:笔者在某一个项目中遇到无论指明什么EntryPoint入口点和CharSet字符集都无法加载一个第三方DLL文件时,就直接自己使用C++ 编写了一个DLL文件来加载这个C#中无法识别加载的第三方DLL,然后在C#中调用自己编写的DLL文件解决了问题。

        本实例源码由VS2010+Silverlight4.0编写,点击 SLLinkDLl.rar 下载本实例源码。点击 IlasLinkDll.rar 下载DLL文件源码。