条件下采用动态链接库dll的安详严整,之间的涉
分类:计算机编程

c 调用c#写的DLL;

1,什么是dll文件?

.h头文件是编写翻译时必得的,lib是链接时索要的,dll是运作时索要的。

在 C# 中通过 P/Invoke 调用Win32 DLL

此随笔演示了树立c#的dll;

DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序扩充”,是软件文件类型。在Windows中,繁多应用程序并非叁个完整的可施行文件,它们被分开成一些对立独立的动态链接库,即DLL文件,放置于系统中。当大家举办某贰个程序时,相应的DLL文件就能被调用。八个应用程序可使用七个DLL文件,一个DLL文件也恐怕被区别的应用程序使用,那样的DLL文件被可以称作分享DLL文件。

叠合正视项的是.lib不是.dll,若生成了DLL,则早晚也生成 LIB文件。假若要瓜熟蒂落源代码的编写翻译和链接,有头文件和lib就够了。假如也使动态连接的程序运维起来,有dll就够了(放在Debug文件夹里卡塔 尔(英语:State of Qatar)。在开拓和调试阶段,当然最棒都有。

 

c 构造建设工程,引进dll;

2,托管dll和非托管dll差异是何等?

.h .lib .dll三者的涉嫌是:

我们在事实上中国人民解放军海军事工业程大学业作学习C#的时候,大概会问:为何我们要为一些早已存在的作用(比如Windows中的一些功效,C 中已经编写制定好的片段方法卡塔尔国要再一次编辑代码,C#有未有一点子能够一向都用那个原本已经存在的成效吗?答案是显著的,大家可以由此C#中的DllImport直接调用这么些效应。
DllImport所在的名字空间 using System.Runtime.InteropServices;
MSDN中对DllImportAttribute的表明是这么的:可将该属性应用于方法。DllImportAttribute 属性提供对从非托管 DLL 导出的函数实行调用所供给的消息。作为最低要求,必得提供带有入口点的 DLL 的称号。
DllImport 属性定义如下:
namespace System.Runtime.InteropServices
{
  [AttributeUsage(AttributeTargets.Method)]
  public class DllImportAttribute: System.Attribute
  {
   public DllImportAttribute(string dllName) {...}
   public CallingConvention CallingConvention;
   public CharSet CharSet;
   public string EntryPoint;
   public bool ExactSpelling;
   public bool PreserveSig;
   public bool SetLastError;
   public string Value { get {...} }
  }
}
  说明:
  1、DllImport只好放置在措施申明上。
  2、DllImport具备单个定位参数:内定包括被导入方法的 dll 名称的 dllName 参数。
  3、DllImport具备七个命名参数:
   a、CallingConvention 参数提醒入口点的调用约定。借使未钦点CallingConvention,则应用默许值 CallingConvention.Winapi。
   b、CharSet 参数提示用在入口点中的字符集。假诺未钦点CharSet,则接收暗中同意值 CharSet.Auto。
   c、EntryPoint 参数给出 dll 中入口点的称号。要是未钦命EntryPoint,则接收办法本人的称呼。
   d、ExactSpelling 参数提示 EntryPoint 是不是必得与提醒的入口点的拼写完全合营。若是未内定ExactSpelling,则应用私下认可值 false。
   e、PreserveSig 参数提示方法的签定应当被保存依然被转变。当签字被撤换时,它被撤换为三个存有 HRESULT 再次来到值和该再次来到值的八个名叫 retval 的增大输出参数的具名。假如未钦定 PreserveSig,则接收暗中认可值 true。
   f、SetLastError 参数提醒方法是不是保留 Win32"上一错误"。假如未钦定SetLastError,则采纳暗中认可值 false。
  4、它是一遍性属性类。
  5、别的,用 DllImport 属性修饰的不二秘诀必需具备 extern 修饰符。

不可能解决的标题:

托管DLL正是能够在国有语言运转库(Common Language Runtime,简单称谓CL帕杰罗卡塔 尔(阿拉伯语:قطر‎中可以间接引用的,而且扩展为“DLL”的文书。具体所指正是包装各样命名空间所在的DLL文件,如System.dll等。非托管DLL就是日常所的动态链接库等,在那之中就总结了打包全部Windows API函数的DLL文件。种种非托管DLL中的函数在公共语言运维库中不能平素被调用,而急需经过.Net框架提供的“平台调用”服务后才足以。(由此可知正是.net情状下转移的动态链接库为托管dll,相反则为非托管dll卡塔 尔(英语:State of Qatar)

H文件效用是:证明函数接口

 

钦赐dll的路线,在代码里面一向写 #using "xxx.dll" 一定要在运用路线 #using "../bin/debug/xxx.dll"

3,托管dll和非托管dll怎么样行使?

DLL文件功效是: 函数可施行代码

 ========================================================

 

托管dll在VS情形下利用相对轻便,能够在品种名上右击选择丰裕应用的措施导入dll,本文这里不作安详严整。非托管dll的使用手续及如下:

当大家在和睦的顺序中援引了五个H文件里的函数,编链器怎么精晓该调用哪些DLL文件呢?那就是LIB文件的成效: 告诉链接器 调用的函数在哪些DLL中,函数实施代码在DLL中的什么岗位,那也正是怎么需求增大正视项 .LIB文件,它起到大桥的效用。假设生成静态库文件,则还未有DLL ,独有lib,那个时候函数可实践代码部分也在lib文件中

 

1-建立c#的dll,过程略;

1,需求检讨采用的dll的目的平台(Any Cpu,x86,x64卡塔尔,在类型属性生成选项卡中精选与dll相对应的对象平台。因为托管dll是在.net的处境下转移的,转变为机器语言后能够自动识别指标平台即有框架援救解释,而非托管不可以和煦分辨要求人工的安装。

当前以lib后缀的库有二种,风姿罗曼蒂克种为静态链接库(Static Libary,以下简称“静态库”),另生机勃勃种为动态连接库(DLL,以下简单的称呼“动态库”)的导入库(Import Libary,以下简单称谓“导入库”卡塔尔国。静态库是三个也许多少个obj文件的包裹,所以有人干脆把从obj文件生成lib的长河称为Archive,即联合到手拉手。举例你链接多个静态库,假使内部有错,它会标准的找到是哪位obj有错,即静态lib只是壳子。动态库经常会有对应的导入库,方便程序静态载入动态链接库,不然你只怕就需求和煦LoadLibary调入DLL文件,然后再手工业GetProcAddress获得对应函数了。有了导入库,你只须要链接导入库后依照头文件函数接口的宣示调用函数就足以了。导入库和静态库的区分相当的大,他们本质是不相通的东西。静态库本人就包蕴了实际上实践代码、符号表等等,而对于导入库来讲,其实际的推行代码位于动态库中,导入库只包罗了地址符号表等,确定保障程序找到相应函数的大器晚成部分大旨地址新闻。

    DllImport是System.Runtime.InteropServices命名空间下的三个属性类,其意义是提供从非托管DLL导出的函数的不可缺少调用新闻。
    DllImport属性应用于方法,供给起码要提供含有入口点的dll的名目。
    DllImport的定义如下:

图片 1

2,使用DllImport导入非托管dll。

诚如的动态库程序有lib文件和dll文件。lib文件是必须在编译期就连选择应用程序中的,而dll文件是运作期才会被调用的。借使有dll文件,那么相应的lib文件日常是一些索引音信,具体的实今后dll文件中。如若独有lib文件,那么那么些lib文件是静态编写翻译出来的,索引和促蒙Trey在当中。静态编写翻译的lib文件有好处:给顾客设置时就无需再挂动态库了。但也会有重疾,就是导致应用程序很大,并且失去了动态库的灵活性,在本子进级时,同时要公布新的应用程序才行。在动态库的情状下,有四个文本,而二个是引进库(.LIB卡塔尔国文件,一个是DLL文件,引进库文件包罗被DLL导出的函数的称号和岗位,DLL包蕴实际的函数和数码,应用程序使用LIB文件链接到所急需选择的DLL文件,库中的函数和数据并不复制到可实施文件中,由此在应用程序的可执行文件中,寄存的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运营是再把程序代码和被调用的函数代码链接起来,进而节省了内部存款和储蓄器财富。从地点的辨证能够见到,DLL和.LIB文件必需随应用程序一齐发行,不然应用程序将会发生错误。

        [AttributeUsage(AttributeTargets.Method)] 
     public class DllImportAttribute: System.Attribute 
     { 
      public DllImportAttribute(string dllName) {…} //定位参数为dllName 
 public CallingConvention CallingConvention; //入口点调用约定 
 public CharSet CharSet;                                   //入口点采用的字符接 
 public string EntryPoint;                                  //入口点名称 
 public bool ExactSpelling;                               //是否必须与指示的入口点拼写完全一致,默认false 
 public bool PreserveSig;                                  //方法的签名是被保留还是被转换 
 public bool SetLastError;                                  //FindLastError方法的返回值保存在这里 
 public string Value { get {…} } 
     } 

 

DllImport会依据以下3种顺序查找dll文件:
1卡塔 尔(英语:State of Qatar)、exe所在目录;
2卡塔尔国、System32索引(系统目录卡塔 尔(英语:State of Qatar);


用法示例:

2.改革出口路线输出为 ../bin/debug; ../bin/release 方便c 能够稳定找到

条件下采用动态链接库dll的安详严整,之间的涉及和功力的区分。3卡塔 尔(英语:State of Qatar)、境况变量目录。(即需求将dll及注重文件放到3个目录中的任何贰个目录中卡塔尔。

静态链接库(Lib)与动态链接库(DLL)的分别

    [DllImport("kernel32")] 
    private static extern long WritePrivateProfileString(string section,string key,string val,string filePath);

图片 2

DllImport的导入准则:
1卡塔尔、方法名与Win API完全同样。假诺在C#中调用时显得完全不一致的法子名称,则要求引入EntryPoint属性,使用别名展现。
2卡塔尔国、函数除需求DllImport类修饰符外,还亟需注解public static extern类型。
3卡塔尔、函数重返值和参数必得和调用的API的一丝一毫等同。

     静态连接库正是把(lib)文件中用到的函数代码直接链接进指标程序,程序运营的时候不再需求任何的库文件;动态链接就是把调用的函数所在文书模块(DLL卡塔 尔(阿拉伯语:قطر‎和调用函数在文书中的地方等音讯链接进指标程序,程序运维的时候再从DLL中检索对应函数代码,因而须要相应DLL文件的支持。

    以上是用来写入ini文件的一个win32api。
    
    用此措施调用Win32API的数据类型对应:DWO本田CR-VD=int或uint,BOOL=bool,预约义常量=enum,结构=struct。  

 

4卡塔尔、必得引进System.Runtime.InteropServices命名空间。

静态链接库与动态链接库都以分享代码的措施,假如利用静态链接库,则无论你愿不愿意,lib 中的指令都全体被平昔包含在终极生成的 EXE 文件中了。不过若使用 DLL,该 DLL 不必被含有在最后 EXE 文件中,EXE 文件实行时能够“动态”地引用和卸载这些与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外七个分别在于静态链接库中无法再包罗别的的动态链接库或然静态库,而在动态链接库中还是能再富含别的的动态或静态链接库。

DllImport会根据顺序自动去寻找之处: 1、exe所在目录 2、System32索引 3、处境变量目录所以只必要你把引用的DLL 拷贝到那多个目录下 就足以不用写路线了 只怕能够那样server.MapPath(.bin*.dll)web中的,同时也是应用程序中的 后来发掘用[DllImport(@"C:OJBinJudge.dll")]如此那般钦点DLL的相对路线就足以不奇怪装载。 那一个标题最常出今后运用 第三方非托管DLL组件的时候,小编的也生龙活虎律是那个时候出的主题材料,Asp.Net Team的合法技术方案如下: 首先须求肯定你援用了哪些组件,那个是托管的,哪些是非托管的.托管的很好办,间接被选拔的急需引用,直接使用的急需拷贝 到bin目录下.非托管的管理会相比较麻烦.实际上,你拷贝到bin未有此外赞助,因为CLENCORE会把文件拷贝到贰个暂且目录下,然后在此运转web,而CL宝马X3只会拷贝托管文件,那正是为什么大家鲜明把非托管的dll放在了bin下却一直以来提醒不可能加载模块了.  具体做法如下:  首先大家在服务器上随意找个地点新建一个索引,假诺为C:DLL  然后,在景况变量中,给Path变量加多这么些目录  最终,把富有的非托管文件都拷贝到C:DLL中.  也许更索性的把DLL放到system32索引  对于能够和煦布置的应用程序,那样未偿不是二个消除办法,不过,假如大家用的是杜撰空间,大家是不可能把注 册PATH变量恐怕把我们友好的DLL拷到system32索引的。相同的时间我们也不自然领会我们的Dll的大意路线。  DllImport里面只好用字符 串常量,而无法用Server.MapPath(@"~/Bin/Judge.dll")来规定物理路线。ASP.NET中要运用DllImport 的,必需在先“using System.Runtime.InteropServices;”但是,作者开掘,调用这种"非托管Dll”异常的快,可能是因为小编的措施须求长途验证 吧,可是实际上是太慢了。经过大器晚成翻商讨,终于想到了四个康健的解决办法首先我们用

3.在解决方案增添C 工程,进度略

DllImport的可选属性参数表明:
EntryPoint         钦赐要调用的 DLL 入口点。 
SetLastError       剖断在实行该方式时是或不是出错(使用 马尔斯hal.GetLastWin32Error API 函数来规定)。C#中暗许值为 false。
CharSet            调节名称及函数中字符串参数的编码方式。私下认可值为 CharSet.Ansi。
ExactSpelling      是还是不是改良入口点以对应差别的字符编码格局。
CallingConvention  钦点用于传递格局参数的调用约定。暗中认可值为 WinAPI。该值对应于基于三15人AMD平台的 __stdcall。
BestFitMapping     是不是启用超级映射功用,默以为 true。最好映射功用提供在还没有相配项时,自动提供相配的字符。不能够映射的字符经常转变为暗中同意的“?”。

“每多个lib文件正是多少函数(假若唯有函数卡塔尔的概念”
lib库有三种,风姿洒脱种是带有了函数所在DLL文件和文书中等高校函授数地点的新闻,称为导出库;生机勃勃种是含有函数代码自个儿,平常现存的DLL,用的是前生机勃勃种库;曾经在DOS下的TC/BC等,是后黄金年代种库。包罗函数原型注明的,是头文件(.h卡塔尔国。

[DllImport("kernel32.dll")] 
private extern static IntPtr LoadLibrary(String path); 

[DllImport("kernel32.dll")] 
private extern static IntPtr GetProcAddress(IntPtr lib, String funcName); 

[DllImport("kernel32.dll")] 
private extern static bool FreeLibrary(IntPtr lib);

 

PreserveSig        托管方法签
名是还是不是调换来重临HRESULT,暗许值为 true(不应转变具名卡塔 尔(阿拉伯语:قطر‎。何况重返值有三个增大的 [out, retval] 参数的非托管签字。  

“通过#include包蕴这么些函数证明的头文件后,大家的应用程序就能够动用lib文件中的函数”

分级收获了LoadLibrary和GetProcAddress函数之处,再经过那四个函数来拿到大家的DLL里面包车型地铁函数。
作者们得以先用Server.Map帕特h(@"~/Bin/Judge.dll")来获得大家的DLL的物理路径,然后再用LoadLibrary举办载入,最终用GetProcAddress获得要用的函数地址

4.新加上的C 工程,引用DLL,同不平日间引入名字空间;

ThrowOnUnmappableChar     调控对转移为 ANSI '?' 字符的不可映射的 Unicode 字符引发那贰个。

还要钦命编写翻译器链接相应的库文件。在IDE情状下,经常是贰次内定全数应用的库文件,编写翻译器本人招来各类模块供给的库;在命令行编写翻译处境下,供给钦赐各个模块调用的库。

以下自定义类的代码完结LoadLibrary的装载和函数调用:

  •   引用库使用 #using "xxx.dll" 这里须要制定dll的绝对路线
  • #pragma managed;  // 告诉编写翻译器,将运用托管代码

  • using namespace CsDll002;  // 引进名字空间

4,c#与c 、c动态链接库的参数怎样对应?

“那她和一直提交那些函数定义的文书,举个例子.cpp文件,和头文件有啥分别,静态链接库有哪些用”
cpp文件是源代码,库文件是编写翻译后的二进制代码,比方您能够调用Windows的API,可是无法看出其源代码同样。

 public class DllInvoke  
    {             
        [DllImport("kernel32.dll")]  
        private extern static IntPtr LoadLibrary(String path); 

        [DllImport("kernel32.dll")]    
        private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);  

        [DllImport("kernel32.dll")]      
        private extern static bool FreeLibrary(IntPtr lib);      

        private IntPtr hLib;    

        public DllInvoke(String DLLPath)    
        {            
            hLib = LoadLibrary(DLLPath);   
        }        

        ~DllInvoke()      
        {         
            FreeLibrary(hLib);   
        }         

        //将要执行的函数转换为委托   
 public Delegate Invoke(String APIName,Type t)      
        {            
            IntPtr api = GetProcAddress(hLib, APIName);    
            return (Delegate)Marshal.GetDelegateForFunctionPointer(api,t);      
        } 
    }

 

C C# 备注

“还也许有不领会的是,静态链接库中的lib文件只要利用,则全体lib文件的剧情都放进了exe文件中,那它是被编译进去依然链接的时候总是进去的呢?”
是在链接的时候将lib链接到指标代码中。

下边代码举办调用

图片 3

short int16 短整型

静态链接库(Lib)
在VC 6.0中new一个称谓为libTest的static library工程,

 public delegate int Compile(String command, StringBuilder inf); 
            //编译 
            DllInvoke dll = new DllInvoke(Server.MapPath(@"~/Bin/Judge.dll")); 
            Compile compile = (Compile)dll.Invoke("Compile", typeof(Compile)); 
            StringBuilder inf; 
            compile(@“gcc a.c -o a.exe“,inf);//这里就是调用我的DLL里定义的Compile函数

5.施用类库

int int32 整型

并新建lib.h和lib.cpp八个文件,lib.h和lib.cpp的源代码如下:

 

 尖号表示托管;这里演示了再次来到值使用援用,和C 调用援用同样,无需钦命特殊字符;

long int64 长整型

//文件:lib.h
#ifndef LIB_H
#define LIB_H
extern "C" int add(int x,int y);   //注明为C编写翻译、连接格局的外表函数
#endif

 

与C#区别,如果c# 写的函数是 int  add(int a, int b, ref int resut)  调用时索要 add(1, 2, ref result);这里C 未有这几个语法必要。

& ref 取地址

//文件:lib.cpp
#include "lib.h"
int add(int x,int y)
{
return x y;
}

 ========================================================

 

* ref 指针

  编写翻译那个工程就获取了三个.lib文件,这么些文件正是三个函数库,它提供了add的遵循。将头文件和.lib文件提交给客户后,顾客就足以直接使用此中的add函数了。

DllImport的用法:
DllImport("MyDllImport.dll")]
private static extern int mySum(int a,int b);

c#中修饰符ref、out的法力及效果与利益

  规范Turbo C2.0中的C库函数(大家用来的scanf、printf、memcpy、strcpy等卡塔尔就源于这种静态库。

一 在C#程序设计中运用Win32类库
常用对应项目:
1、DWO宝马7系D 是 4 字节的卡尺头,因而大家能够利用 int 或 uint 作为 C# 对应类型。
2、bool 类型与 BOOL 对应。

ref 须求参数在传递给函数前要最早化,out则没有必要,何足为奇于阳台调用中。out和ref传递的都是援引实际不是值,out侧重于出口使用早先不需赋值而ref在使用早前要求赋值,其余那三个至关心注重要字能够变相完毕使一个办法输出多少个值。ref能够把参数的数值传递进函数,然而out是要把参数清空,便是说你不可能把贰个数值从out传递步入的,out进去后,参数的数值为空,所以你必得开头化一遍。这几个就是五个的界别,或然说就好像有的网上朋友说的,ref是有进有出,out是只出不进。表达是援用的传递。

下边来拜会怎么选取那个库,在libTest工程所在的工作区内new多少个libCall工程。libCall工程仅包蕴一个main.cpp文件,它亲自过问了静态链接库的调用方法,其源代码如下:

演示一:调用 Beep() API 来发出声音
Beep() 是在 kernel32.lib 中定义的,在MSDN 中的定义,Beep具备以下原型:
BOOL Beep(DWOKugaD dwFreq, // 声音频率
DWO君越D dwDuration // 声音持续时间);
用 C# 编写以下原型:
[DllImport("kernel32.dll")]
public static extern bool Beep(int frequency, int duration);

example:

#include <stdio.h>
#include "..lib.h"//不可错过
#pragma comment( lib, "..\debug\libTest.lib" )  //钦赐与静态库一齐三番五次
int main(int argc, char* argv[])
{
     printf( "2 3 = %d", add( 2, 3 ) );
}
  静态链接库的调用正是那般轻松,或者我们每一日都在用,可是大家尚无清楚那些概念。代码中#pragma comment( lib , "..\debug\libTest.lib" )的情致是指本文件生成的.obj文件应与libTest.lib一同接二连三

身体力行二:枚举类型和常量
MessageBeep() 是在 user32.lib 中定义的,在MSDN 中的定义,MessageBeep具备以下原型:
BOOL MessageBeep(UINT uType // 声音类型
);

//命名空间


用C#编辑一下原型:
public enum BeepType
{
  SimpleBeep = -1,
  IconAsterisk = 0x00000040,
  IconExclamation = 0x00000030,
  IconHand = 0x00000010,
  IconQuestion = 0x00000020,
  Ok = 0x00000000,
}
uType 参数实际上接收风度翩翩组预先定义的常量,对于 uType 参数,使用 enum 类型是合乎情理的。
[DllImport("user32.dll")]
public static extern bool MessageBeep(BeepType beepType);

using System.Runtime.InteropServices;

用VC 生成静态库文件
今日闲着没事做,自身写了一些小笔记,不精晓对于新手有没用,高手就绝不看了,作为生手的小编冷眼阅览胆来刊登七个笔记,正是静态库文件的包装进度,使用VC 6.0编写,上边是本文,可能笔者的措辞并不伦不类

以身作则三:管理组织
不经常作者急需规定本人台式机的电瓶意况。Win32 为此提供了电源处理函数,找寻MSDN 能够找到GetSystemPowerStatus() 函数。
BOOL GetSystemPowerStatus(
  LPSYSTEM_POWER_STATUS lpSystemPowerStatus
);
此函数包涵指向有个别组织的指针,我们未有对此进行过管理。要管理组织,大家要求用 C# 定义结构。大家从非托管的定义起初:
typedef struct _SYSTEM_POWER_STATUS {
BYTE  ACLineStatus;
BYTE  BatteryFlag;
BYTE  BatteryLifePercent;
BYTE  Reserved1;
DWORD BatteryLifeTime;
DWORD BatteryFullLifeTime;
} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;
   然后,通过用 C# 类型代替 C 类型来获得 C# 版本。
struct SystemPowerStatus
{
  byte ACLineStatus;
  byte batteryFlag;
  byte batteryLifePercent;
  byte reserved1;
  int batteryLifeTime;
  int batteryFullLifeTime;
}
诸有此类,就足以一本万利地编写出 C# 原型:
[DllImport("kernel32.dll")]
public static extern bool GetSystemPowerStatus(
  ref SystemPowerStatus systemPowerStatus);
   在这里原型中,大家用“ref”指明将传递结构指针并非结构值。那是拍卖通过指针传递的构造的相似方法。
   此函数运维特出,但是最为将 ACLineStatus 和 batteryFlag 字段定义为 enum:
  enum ACLineStatus: byte
   {
    Offline = 0,
    Online = 1,
    Unknown = 255,
   }
   enum BatteryFlag: byte
   {
    High = 1,
    Low = 2,
    Critical = 4,
    Charging = 8,
    NoSystemBattery = 128,
    Unknown = 255,
   }
请小心,由于协会的字段是某些字节,因而大家利用 byte 作为该 enum 的主干项目

//导入非托管dll

先前我们写C/C 源文件的时候,都以先将各类写好的源文件编写翻译,编写翻译生成的是指标文件机器码,即.obj文件.(目的文件的扩张名不一定是.obj文件卡塔 尔(英语:State of Qatar).

演示四:管理字符串

//分配的库管理和接二连三到数控钦定的IP地址或主机名。

大家调用的规范C/C 函数机器码实际被包裹于规范C/C 静态库文件中的.即那多少个扩充名叫.lib的文书中.

二 C# 中调用C 代码
int 类型
[DllImport(“MyDLL.dll")]
//返回个int 类型
public static extern int mySum (int a1,int b1);
//DLL中申明
extern “C” __declspec(dllexport) int WINAPI mySum(int a2,int b2)
{
//a2 b2无法退换a1 b1
//a2=..
//b2=...
return a b;
}

[DllImport("Fwlib64.dll", EntryPoint = "cnc_allclibhndl3", CallingConvention=CallingConvention.Cdecl)]

最后链接器将大家编写翻译的逐一指标文件里的机器码和静态库(规范C/C 库卡塔 尔(英语:State of Qatar)中的函数机器码链接到一同造成二个恢弘名叫.exe的可实践文件模块.

//参数字传送递int 类型
public static extern int mySum (ref int a1,ref int b1);
//DLL中申明
extern “C” __declspec(dllexport) int WINAPI mySum(int *a2,int *b2)
{
//能够转移 a1, b1
*a2=...
*b2=...
return a b;
}

//short (const char *ipaddr, unsigned short port, long timeout, unsigned short *FlibHndl)

在此边大家陈诉将C/C 源文件编写翻译链接成多少个静态库文件,但它不是可施行模块,它体内含有可进行机器码

DLL 需传入char *类型
[DllImport(“MyDLL.dll")]
//传入值
public static extern int mySum (string astr1,string bstr1);
//DLL中申明
extern “C” __declspec(dllexport) int WINAPI mySum(char * astr2,char * bstr2)
{
//修正astr2 bstr 2 ,astr1 bstr1不会被转移
return a b;
}

private static extern Int16 cnc_allclibhndl3(ref String ip, UInt16 port, Int64 timeout, ref UInt16 flibHndl);

静态库文件就好像叁个储藏室或然容器,里面封装了某些可进行机器码.那个机器码是大家用程序设计语言,比方C/C 源文件编写翻译后生成的机器码.

DLL 需传出char *类型
[DllImport(“MyDLL.dll")]
// 传出值
public static extern int mySum (StringBuilder abuf, StringBuilder bbuf );
//DLL中申明
extern “C” __declspec(dllexport) int WINAPI mySum(char * astr,char * bstr)
{
//传出char * 改动astr bstr -->abuf, bbuf能够被转移
return a b;
}

(收拾,源小说来源于互连网)

生龙活虎.下边将切磋将C/C 源文件编写翻译并链接成一个静态库文件的历程,

DLL 回调函数

在VC 6.0中选取File-New-Win32 Static Library,写好工程名创设好职业空间后再选取菜单中New-File来为工程增添C或然C 源文件.

BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)

若果大家为该工程增多了叁个名称为lib_c.c和三个名叫lib_cpp.cpp的源文件

using System;
using System.Runtime.InteropServices;
public delegate bool CallBack(int hwnd, int lParam); //定义委托函数类型
public class EnumReportApp
{
[DllImport("user32")]
public static extern int EnumWindows(CallBack x, int y);
public static void Main() {
CallBack myCallBack = new CallBack(EnumReportApp.Report); EnumWindows(myCallBack, 0);
}
public static bool Report(int hwnd, int lParam)
{
Console.Write("Window handle is ");
Console.WriteLine(hwnd); return true;
}
}

//lib_c.c中的内容

DLL 传递结构
BOOL PtInRect(const RECT *lprc, POINT pt);

extern int Add(int x,int y) //该函数是七个外表函数,任何公文都得以访谈它

using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct Point {
public int x;
public int y;
}
[StructLayout(LayoutKind.Explicit)]
public struct Rect
{
[FieldOffset(0)] public int left;
[FieldOffset(4)] public int top;
[FieldOffset(8)] public int right;
[FieldOffset(12)] public int bottom;
}
Class XXXX {
[DllImport("User32.dll")]
public static extern bool PtInRect(ref Rect r, Point p);
}

{
    return x y;

}

extern int data_c
//那是三个外部全局变量,任何公文能够访谈它

//lib_cpp.cpp中的内容

extern “C” int
        reduce(int x,int y)//这里加了个”C”表示同意C源文件访谈这么些C 函数代码

{
    return x-y;

}

extern “C” int data_cpp=2;

小心以下几点

(1)当“extern”关键字修饰在函数或全局变量的定义中时,表示该函数或全局变量任何公文可以访谈,“extern”关键字可以简简单单不写,缺省下便是”extern”

  当“extern”关键字修饰在函数评释或全局变量证明中时,表示节制当前文件只好引用用“extern”关键字修饰定义的函数或全局变量.

(2)当”static”关键字修饰在函数或全局变量的概念中时,表示该函数或全局变量只好由本文件中加了”static”关键字修饰的函数注解或全局变量证明来引用.

  当”static”关键字修饰在函数申明或全局变量注脚中时,表示限制当前文件只好援用用“static”关键字修饰定义的函数或全局变量.

(3)在CPP源文件的函数和全局变量定义中加了个”C”表示同意C源文件访问该函数和全局变量.要是是C 源文件访它们的话则可加可不加.注意那”C”要大写.

接下去将在将写好的C/C 源文件实行编写翻译和链接,最后会生成多少个扩张名字为.lib的文件.该文件正是静态库文件了,该静态库文件是不能够向来运转的,大家所编写翻译的C/C 源文件的机器码就早就被卷入进这些用VC 6.0创建的静态库文件之中去了.

二.如何将编制好的静态库文件像使用C/C 规范库那样选取,上面将接二连三斟酌

1.用VC 6.0新建四个工程名叫TEST,增添一个名称叫TEST.c的源文件到该工程,因为我们将测量检验一下,将我们编辑的库文件里的函数大概全局变量的机械码链接到我们以此TEST.c源文件中去,假诺大家调换的库文件名称为TEST.lib,先拷贝如下轨范代码到TEST.c中

//TEST.c

#include <stdio.h>

extern int
Add(int x,int y); //当前文件只可以访谈“extern”关键字修饰定义的Add函数

extern int
reduce(int x,int y);// //当前文件只能访谈“extern”关键字修饰定义的reduce函数

#pragma comment(lib,"TEST.lib") //提示链接器到字符串所表示的文件路线中去找库文件

int main()

{
    printf("%dn",Add(2,3));
    printf("%dn",reduce(3,2));
    return 0;

}

此地我们要表明静态库中已知的函数或全局变量的扬言

#pragma comment(lib,"TEST.lib")那条指令告诉链接器到字符串所表示的门径下去找库文件,这里自个儿将库文件放到了日前工程目录下.也得以不写那句.

再有黄金时代种艺术,能够直接在VC 6.0中安装依次选用tools、options、directories、library files菜单或选拔,填入库文件路线(只键入库文件所在目录路线而无法输入库文件名卡塔尔,那只是报告链接器库文件所在目录的渠道,还未有告诉链接器库文件名,方法是VC 6.0中装置依次选择project-settings-link 在object/library modules: 那栏输入库文件名字然后就OK了

2.当用C 源文件的靶子文件和库文件的代码链接时有一点点小改动,这里就不浪费口舌了,假若我们新建了叁个工程并增加了一个名字为TEST.CPP的源文件,拷贝如下楷模代码到TEST.CPP中

//TEST.cpp

#include <stdio.h>

extern “C” int
       Add(int x,int y); //表示援用的是C函数代码

extern int
      reduce(int x,int y);

#pragma comment(lib,"TEST.lib")

int main()

{
    printf("%dn",Add(2,3));
    printf("%dn",reduce(3,2));
    return 0;

}

在这几个C 源文件里援用C函数代码同样要加个”C”,不过在C源文件引用C 函数代码无法加”C ”,编写翻译会报错,只可以在C 文件函数定义中加”C”.

唯有C 才补助这种引用方式,只怕因为独有C 宽容C而还未C包容C 那后生可畏原则.

 

 

.h用于编写翻译阶段的稽审,如在math.h中有函数表明:
int abs(int);
但是在使用中写为
#include <math.h>
...abs(3,5);
编写翻译器阶段就能够检查评定出荒诞。

.dll用于运转阶段,如调用SetWindowText()函数等,须要在user32.dll中找到该函数。DLL能够差超级少感觉是风姿罗曼蒂克种含有供外人调用的函数和能源的可实行文件。

.lib用于链接阶段,在链接各部分目的文件(平时为.obj卡塔 尔(阿拉伯语:قطر‎到可履行文件(平日为.exe卡塔尔进程中,须求在.lib文件中找找动态调用函数(平日为DLL中的函数卡塔尔国之处音信,当时内需在lib文件中搜索,如搜寻SetWindowText()函数的地址偏移就须求查找user32.lib文件。(.lib也可用以静态链接的内嵌代码卡塔尔

 

lib和dll文件的分别和关系    
   
  .dll是在你的程序运营的时候才连接的公文,因而它是风流倜傥种十分的小的可施行文件格式,.dll还应该有别的的文件格式如.ocx等,全数的.dll文件都以可实行。  
   
  .lib是在您的次第编写翻译连接的时候就接连的文件,因而你一定要告知编写翻译器连接的lib文件在此。常常的话,与动态连接文件相对照,lib文件也被称呼是静态连接库。当你把代码编写翻译成那二种格式的文件时,在事后他们就不只怕再被改换。若是你想行使lib文件,就务须:  
  1?   包括三个一呼百应的头文件报告编写翻译器lib文件之中的具体内容  
  2?   设置lib文件允许编写翻译器去搜求已经编写翻译好的二进制代码  
   
  假如您想从您的代码分离一个dll文件出来代替静态连接库,依旧必要八个lib文件。这些lib文件将被连选择程序告诉操作系统在运作的时候你想用到何等dll文件,通常意况下,lib文件里有相应的dll文件的名字和叁个指明dll输出函数入口的顺序表。假如不想用lib文件或然是平素不lib文件,能够用WIN32   API函数LoadLibrary、GetProcAddress。事实上,大家能够在Visual   C    IDE中以二进制方式张开lib文件,多数意况下会见到ASCII码格式的C 函数或一些重载操作的函数名字。  
   
  日常大家最要害的关于lib文件的分神就是出新unresolved   symble   那类错误,那就是lib文件延续错误也许未有满含.c、.cpp文件到工程里,关键是意气风发旦在C 工程里用了C语言写的lib文件,就必定要这么含有:  
  extern   "C"  
  {  
  #include   "myheader.h"  
  }  
  这是因为C语言写的lib文件未有C 所必需的名字破坏,C函数无法被重载,因而连接器会出错。

 

C语言中有局地函数不须求实行编写翻译,有意气风发部分函数也得以在八个文本中接收。日常的话,这个函数都会推行一些标准职责,如数据库输入/输出操作或显示器调节等。能够先行对这么些函数举办编写翻译,然后将它们放置在有的非同一般的靶子代码文件中,这个目的代码文件就称为库。库文件中的函数能够通过三回九转程序与应用程序进行三番两次。那样就无需在历次开荒顺序时都对那一个通用的函数实行编译了。    
   
    分歧档期的顺序的应用程序将会接纳分歧的函数库。比方:libdbm库中组包罗了对数据库文件进行拜会的dbm函数,须求对数据库实行操作的程序就可以与该库举办一而再延续。数学应用程序将采取数学库libm,X-Windows应用程序将采纳Xlib库,libX11。此外,全部的前后相继都将运用标准的C函数库。libc,该库中蕴含了诸好内部存款和储蓄器管理或输入输出操作的中央函数,那几个库都存放在/usr/lib那些体系公用的目录中,系统中的任何客户都足以利用这么些库。当然顾客也能够创造协调专项使用的库函数,供本身或其余钦赐的职员动用。    
   
    库可以有三种接纳的样式:静态、分享和动态。静态库的代码在编译时就已连接到开拓人士开荒的应用程序中,而分享库只是在前后相继开头运营时才载入,在编写翻译时,只是轻易地钦定必要选拔的库函数。动态库则是分享库的另生机勃勃种变化情势。动态库也是在程序运转时载入,但与分享库分裂的是,使用的库函数不是在程序运维起头,而是在前后相继中的语句需求使用该函数时才载入。动态库能够在程序运营时期保释动态库所占有的内部存款和储蓄器,腾出空间供别的程序行使。由于分享库和动态库并从未在前后相继中总结库函数的内容,只是包罗了对库函数的引用,由此代码的局面超小。

 

lib是静态库,dll日常是动态链接库(也会有非常的大可能率是其余卡塔 尔(阿拉伯语:قطر‎

诸如要编写翻译个exe,lib在编写翻译的时候就能被编写翻译到exe里,作为程序的一片段

而dll是不被编写翻译进去,是运作的时候才调入的(可能是exe刚运维就调入,也可能运行了四分之二才调入卡塔 尔(阿拉伯语:قطر‎

用法,lib要求个.lib文件和二个.h文件,程序正常化使用.h的函数,在链接选项里加入.lib文件就ok

dll用法有2种,一是 .h .lib .dll的,用法和最近相似,中间的lib是个换车,运维的时候会调用dll
二是:直接用dll,须求精通dll的函数定义,用LoadLibrary和GetProcAddress把函数指针抽出来,看msdn的事例吗

本文由pc28.am发布于计算机编程,转载请注明出处:条件下采用动态链接库dll的安详严整,之间的涉

上一篇:cookie和session 下一篇:没有了
猜你喜欢
热门排行
精彩图文