ASP.net动态调用非托管DLL的参数传递问题
作者:骄傲的猫 出处:http://blog.youkuaiyun.com/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