C#如何调用一个非托管动态库中的函数呢,比如用VC6写的动态库,总之C#调用动态库的过程是比Java调用DLL动态库方便快捷多了,下面举例说明这个过程。
1、创建一个非托管动态库
代码如下:
//这一句是声明动态库输出一个可供外不调用的函数原型. extern "C" __declspec(dllexport) int add( int , int );int add( int a, int b) { //实现这个函数returna+b; }
保存成C或者CPP文件都可以,接下来就用命令 cl (这个命令VC6提供) 来编译生成一个动态库,命令如下:
C:\>cl /LD MyLib.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86 Copyright (C) Microsoft Corp 1984-1998. All rights reserved.MyLib.cpp Microsoft (R) Incremental Linker Version 6.00.8447 Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
/out:MyLib.dll /dll /implib:MyLib.lib MyLib.obj Creating library MyLib.lib and object MyLib.exp
2、编写C#程序调用动态库
using System; using System.Runtime.InteropServices; //这是用到DllImport时候要引入的包 public class InvokeDll{[DllImport( "MyLib.dll" , CharSet=CharSet.Auto)] staticexternint add( int a, int b); //声明外部的标准动态库, 跟Win32API是一样.
public static void Main() { Console.WriteLine(add(10,30)); } }
C:\>csc InvokeDll.cs Microsoft (R) Visual C# .NET 编译器版本 7.10.3052.4 用于 Microsoft (R) .NET Framework 版本 1.1.4322 版权所有 (C) Microsoft Corporation 2001-2002。保留所有权利。 将生成Invokedll.exe, 可以执行该文件.C:\>InvokeDll 40
回过头来,如果我们在MyLib.cpp中没有加上 extern"C" 在,那么C中通过函数名 add 定位不到导出方法(因为函数名在动态库中已经变了),执行invokeDll时就会出现如下错误。
C:\>InvokeDll未处理的异常: System.EntryPointNotFoundException: 无法在 DLL MyLib.dll 中找到名为 add 的入口点。 at InvokeDll.add(Int32 a, Int32 b) at InvokeDll.Main()
[注:]本文参考着网上一篇文章:C-Sharp调用标准动态库 ,但是直接照着原文的操作就是会无法定位 add 的入口点的错误,所以略有修改。