C#挪用非托管靜態庫中的函數辦法。本站提示廣大學習愛好者:(C#挪用非托管靜態庫中的函數辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是C#挪用非托管靜態庫中的函數辦法正文
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 的進口點的毛病,所以略有修正。