ASP.Net動態調用非托管DLL的參數傳遞問題
作者:驕傲的貓
出處:http://blog.csdn.Net/shardowm
最近由於工作的原因碰到了在ASP.Net調用非托管DLL參數傳遞的問題,結果花了半天時間終於比較完美的解決。特此寫這篇文章與大家分享。這裡主要講解調用DLL時 參數傳遞的問題,對於如何調用非托管DLL網上有很多文章這裡就不在重復了。
LibInvoke是在ASP.Net環境下調用非托管DLL了,在類中Invoke方法創建DLL中指定方法的Delegate 對象。
public class LibInvoke
...{
...
public Delegate Invoke(string APIName, Type t)
...{
if (hLib == IntPtr.Zero)
throw(new Exception("未載入有效的DLL模塊, 請確認DLL文件: " + strDLL + "是否有效!" ));
IntPtr hApi = IntPtr.Zero;
hApi = GetProcAddress(hLib, APIName);
if (hApi == IntPtr.Zero)
throw(new Exception("無效的函數名: " + APIName));
return Marshal.GetDelegateForFunctionPointer(hApi, t);
}
}
一. 內置類型
對於內置類型(整型、布爾型、字符型)參數的傳遞是最簡單的,只要直接傳參數,並且直接處理返回值就可以了。
private delegate bool Func1(int a, char b);
public bool BaseTypeTest
...{
Func1 fun = (Func1)objInvoke.Invoke("BaseTypeTest", typeof(Func1));
bool res = fun(1, ''A'');
return res
}
二. 字符串類型
傳入字符串時由於字符串編碼問題的,有可能造成字符串到DLL中後變成亂碼,所以在這裡現將字符串都轉換成byte型的數組,然後再作為參數傳入到dll的函數中。
private delegate bool Func2(byte[] _appID, byte[] _paramVal);
public bool StringTypeTest1(string appID, string paramValue)
...{
Encoding e1 = Encoding.GetEncoding(936);
byte[] b1 = e1.GetBytes(appID);
byte[] b2 = e1.GetBytes(paramValue);
Func2 func = (Func2)objInvoke.Invoke("StringTypeTest1", typeof(Func2));
bool result = func(b1, b2);
return result;
}
如果dll中要返回一個字符串,則返回字符串只能作為函數的引用參數,而不能直接讓函數返回一個字符串。以下代碼就是調用dll中的
void StringTypeTest2(char** a)
函數。
private delegate void Func3(out StringBuilder ret);
public string StringTypeTest2
...{
StringBuilder obj= new StringBuilder();
Func3 func= (_Author)objInvoke.Invoke("StringTypeTest2", typeof(Func3));
func(out obj);
return obj.ToString();
}
所以在這裡應該注意,在實現返回string或對象類型的函數是,不要讓函數直接返回字符串或對象,而應把需要返回的字符串或對象作為引用參數。
參考文獻:
[1] 《在 C# 中通過 P/Invoke 調用Win32 DLL》 Jason Clark ,
網址:http://www.microsoft.com/china/msdn/library/langtool/vcsharp/ousNET.mspx