1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > C#调用非托管Dll

C#调用非托管Dll

时间:2020-05-05 21:57:49

相关推荐

C#调用非托管Dll

最近在项目中碰到需要调用非托管C++生成的dll,下面将自己遇到的问题,以及解决的办法总结如下:

1.

问题:

我们通常去映射dll的方法是使用

publicconststringdllPath=path;

[DllImport(dllPath+"test.dll",EntryPoint="test()",SetLastError=true,

CharSet=CharSet.Ansi,ExactSpelling=true,CallingConvention=CallingConvention.Cdecl)]

publicstaticexterninttest(); 这种方式有一个致命的缺陷,dll文件路径dllPath必须为const,而const是编译时常量,也就是说dllPath赋值必须是字符串常量,如果你想动态指定dll文件路径用这种方式基本上没办法实现,下面是一种解决方案。

解决方案:

[DllImport("Kernel32.dll")]

publicstaticexternIntPtrLoadLibrary(stringlpFileName);

[DllImport("kernel32.dll",SetLastError=true)]

publicstaticexternintGetProcAddress(

IntPtrhModule,stringlpProcName);

[DllImport("kernel32.dll",EntryPoint="FreeLibrary",SetLastError=true)]

publicstaticexternboolFreeLibrary(IntPtrhModule);

这种方式有点像C#的反射,先引入这3个API 函数:

LoadLibrary(string lpFileName)是加载指定的dll文件,参数lpFileName为dll文件的路径,返回的为该dll的实例(指针)

GetProcAddress(IntPtr hModule,string lpProcName)是获取dll中指定的方法委托,参数hModule为LoadLibrary()方法返回的值,lpProcName方法名,返回值为指定方法的委托,注意要强制转换.

FreeLibrary(InPtr hModule)是释放加载的dll文件,参数hModule为LoadLibrary()返回值.

有了这些方法就能很容易的实现动态加载dll。

代码:

//dll实例

staticprivateIntPtrinstance;

//要加载方法的委托

delegatevoidTest();

//导入引擎dll

[DllImport("Kernel32.dll")]

publicstaticexternIntPtrLoadLibrary(stringlpFileName);

[DllImport("kernel32.dll",SetLastError=true)]

publicstaticexternintGetProcAddress(

IntPtrhModule,stringlpProcName);

[DllImport("kernel32.dll",EntryPoint="FreeLibrary",SetLastError=true)]

publicstaticexternboolFreeLibrary(IntPtrhModule);

//获取方法指针

staticprivateDelegateGetAddress(IntPtrdllModule,stringfunctionname,Typet)

{

intaddr=GetProcAddress(instance,functionname);

if(addr==0)

returnnull;

else

returnMarshal.GetDelegateForFunctionPointer(newIntPtr(addr),t);

}

//加载DLL

staticpublicvoidLoadLib()

{

stringdllPath;

dllPath=ConfigurationSettings.AppSettings["dllPath"].ToString();

instance=LoadLibrary(dllPath);

if(instance.ToInt32()==0)

{

thrownewLoadLibraryException("请在App.Config中配置引擎DLL的路径!");

}

}

///<summary>

///卸载DLL

///</summary>

staticpublicvoidFreeLib()

{

FreeLibrary(instance);

}

///<summary>

///实例

///</summary>

///<paramname="iptr"></param>

///<returns></returns>

staticpublicvoidtest()

{

try

{

Testtemp=(Test)GetAddress(instance,"test",typeof(Test));

returntemp();

}

catch(Exceptionex)

{

thrownewLoadLibraryException("");

}

}

//mydll.cpp

int f(int a, char* b, int* c)

{

return(10);

}

//mydll.def

LIBRARY MyDll

EXPORTS

f @1

//c#

[DllImport("mydll.dll")]

public static extern int f(int a,StringBuilder b,ref int c);

static void Main(string[] args)

{

StringBuilder b=new StringBuilder(10);

int c=0;

Console.WriteLine("{0}",f(10,b,ref c));

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。