C# 調用其他的動態庫開發應注意的問題

來源:互聯網
上載者:User

標籤:des   cWeb   使用   os   io   檔案   for   art   

1.背景

程式開發語言可以說是五花八門,這就引出了一個新問題 ,不同語言開發的系統進行對接時相關調用的問題。

下面我主要說一下我自己在做介面開發時遇到的問題及解決方案僅供參考,我使用的C#開發進行對接其他程式。

2.具體做法

 首先,談一下目前系統對接的幾種常見對接方式。a.通過非託管的動態庫dll檔案匯入。b.通過對方提供的COM組件調用。c.通過webService進行調用。

目前比較常用的就這個幾種。下面一起看看都是如何具體調用實現以及遇到的問題。

a.通過非託管的動態庫dll檔案匯入

此種方式在C#中的通用聲明方式如下 。假如提供的dll 是InterfaceHN.dll   裡面提供的方法        long init( char *Addr, int Port, char *Servlet)

[DllImport("InterfaceHN.dll")]  這裡面還可以用  EntryPoint = "init",  CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true 屬性指定更詳細的資訊 大家可以嘗試一下 ,一般情況下只要指定函數進入點就行例如[DllImport("InterfaceHN.dll", EntryPoint = "init")]

public static extern Int32 init( [MarshalAs(UnmanagedType.VBByRefStr)] ref string addr, Int32 port, [MarshalAs(UnmanagedType.VBByRefStr)] ref string servlet);

public static extern Int32 init( [ StringBuilder  addr, Int32 port,  StringBuilder servlet); 

在這種方式中,我以前遇到過的問題是記憶體保護,沒有改方法 ,調用方法返回的值不正確等等問題。

這塊就要注意參數的類型是不是兩種語言都支援的,或者說是兩種語言共有的 ,上面我就遇到過 ,文檔上描述的是返回long  值 ,但是實際上返回的是Int32  導致這邊出現記憶體保護提示。還有一點就是對於,帶有參數傳回值的這種情況 ,在C#一般字串使用 StringBuilder  就可以 ,不行的話試一試[MarshalAs(UnmanagedType.VBByRefStr)] ref string  paras  這種方式。出問題之後,首先自己檢查參數類型對不對,一般對方是不會有問題的,但也不排除對方給的dll本身就有問題。

b.通過對方提供的COM組件調用。

這種方式比較簡單,因為他本身就是一種介面標準。使用時只要註冊它,然後添加引用把它引入你的程式。執行個體化相關的對象就可以使用了。

具體註冊方法 :在系統運行視窗中輸入regsvr32 +com組件的地址 例如regsvr32 D:公用程式集\RM.ReportEngine.dll   取消註冊是在後面添加/u 開關。

c.通過webService進行調用。

此種調用也是目前比較方便流行的一種。只要給出服務的地址就可以進行 。但是有些環境你沒法訪問。例如vpn ,專網等等。這時就不能直接通過添加服務的方式進行訪問了,但是可以通過得到他們的服務描述xml檔案進行訪問,如果還不行,就自己通過反射的方式建立用戶端代理具體如下:

public class WebServiceHelper
{
#region InvokeWebService 動態調用web服務

/// <summary>
/// 動態調用WebService
/// </summary>
/// <param name="url">WebService地址</param>
/// <param name="methodname">方法名(模組名)</param>
/// <param name="args">參數列表</param>
/// <returns>object</returns>
public static object InvokeWebService(string url, string methodname, object[] args)
{
return WebServiceHelper.InvokeWebService(url, null, methodname, args);
}
/// <summary>
/// 動態調用WebService
/// </summary>
/// <param name="url">WebService地址</param>
/// <param name="classname">類名</param>
/// <param name="methodname">方法名(模組名)</param>
/// <param name="args">參數列表</param>
/// <returns>object</returns>
public static object InvokeWebService(string url, string classname, string methodname, object[] args)
{
try
{

string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling";
if ((classname == null) || (classname == ""))
{
classname = WebServiceHelper.GetWsClassName(url);
}

//擷取WSDL
WebClient wc = new WebClient();
Stream stream = wc.OpenRead(url + "?WSDL");
ServiceDescription sd = ServiceDescription.Read(stream);
ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
sdi.AddServiceDescription(sd, "", "");
CodeNamespace cn = new CodeNamespace(@namespace);

//產生用戶端代理類代碼
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(cn);
sdi.Import(cn, ccu);
CSharpCodeProvider csc = new CSharpCodeProvider();
ICodeCompiler icc = csc.CreateCompiler();

//設定編譯參數
CompilerParameters cplist = new CompilerParameters();
cplist.GenerateExecutable = false;
cplist.GenerateInMemory = true;
cplist.ReferencedAssemblies.Add("System.dll");
cplist.ReferencedAssemblies.Add("System.XML.dll");
cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
cplist.ReferencedAssemblies.Add("System.Data.dll");

//編譯代理類
CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
if (true == cr.Errors.HasErrors)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
{
sb.Append(ce.ToString());
sb.Append(System.Environment.NewLine);
}
throw new Exception(sb.ToString());
}

//組建代理程式執行個體,並調用方法
System.Reflection.Assembly assembly = cr.CompiledAssembly;
Type t = assembly.GetType(@namespace + "." + classname, true, true);
object obj = Activator.CreateInstance(t);
System.Reflection.MethodInfo mi = t.GetMethod(methodname);
if (args == null)
return mi.Invoke(obj, null);
else
return mi.Invoke(obj, args);
}
catch (Exception ex)
{
throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));
}
}

private static string GetWsClassName(string wsUrl)
{
string[] parts = wsUrl.Split(‘/‘);
string[] pps = parts[parts.Length - 1].Split(‘.‘);

return pps[0];
}
#endregion
}

通過類WebServiceHelper這的方法  InvokeWebService(string url, string methodname, object[] args) 完成對方webservice 的調用。

一般在調用其他系統的東西時經常出現記憶體問題,找不到方法問題,無法串連問題,傳回值不是值期望的值問題。這些問題只要仔細認真的分析

就可以解決,沒有啥太難的東西。希望對你有協助。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.