当前位置: 移动技术网 > IT编程>开发语言>c# > C#调用非托管动态库中的函数方法

C#调用非托管动态库中的函数方法

2019年07月18日  | 移动技术网IT编程  | 我要评论
c#如何调用一个非托管动态库中的函数呢,比如用vc6写的动态库,总之c#调用动态库的过程是比java调用dll动态库方便快捷多了,下面举例说明这个过程。 1、创建一个非托

c#如何调用一个非托管动态库中的函数呢,比如用vc6写的动态库,总之c#调用动态库的过程是比java调用dll动态库方便快捷多了,下面举例说明这个过程。

1、创建一个非托管动态库

代码如下:

复制代码 代码如下:

   //这一句是声明动态库输出一个可供外不调用的函数原型. 
   extern   "c"  __declspec(dllexport)  int  add( int ,  int ); 

   int  add( int  a, int  b)  
   { 
        //实现这个函数returna+b; 
   }


注意上面代码,一定要加上 extern"c" ,不能生成的动态库中的导出函数名就不会是add,而是像 ?add@@yahhh@z 样子,后面只是通过函数名 add 来定位函数入口就会出问题。

保存成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


可以看到在c盘根目录下生成了你要的动态库 mylib.dll ,还伴随着生成了mylib.lib、mylib.obj、mylib.exp文件,上面命令cl的参数/ld就是生成动态库文件

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)); 
       } 
   }


保存为invokedll.cs文件, 与mylib.dll置于同一目录, 编译该文件.
复制代码 代码如下:

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


我们看到c#调用了非托管动态库的函数 add 。执行前保证 mylib.dll 在能够被 invokedll 程序加载到的路径上。

回过头来,如果我们在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()


对于没有加上 extern "c" 的函数原型生成的动态库,我们就得用别的方式来调用了,具体怎么做,我现在还不知道。下面还有一个问题,上面的例子只是演示了动态库中函数非常简单的情况,如果函数传递的参数是指针,或者更复杂的数据类型,又如何操作呢?以后会深究的。

[注:]本文参考着网上一篇文章:c-sharp调用标准动态库 ,但是直接照着原文的操作就是会无法定位 add 的入口点的错误,所以略有修改。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网