首页 > 编程语言 >C#的DllImport使用方法

C#的DllImport使用方法

时间:2024-07-10 12:25:50浏览次数:16  
标签:string C# DllImport 托管 public DLL 方法 代码

1. 托管代码与非托管代码

托管代码:我们编写的C#代码(也包括.net平台上的其他语言,如VB,J#等),首先经过编译器把代码编译成中间语言(IL),当方法被调用时,公共语言运行库CLR把具体的方法编译成适合本地计算机运行的机器码,并且将编译好的机器码缓存起来,以备下次调用使用。

托管代码的源代码在运行时分为两个阶段:  ①源代码编译为托管代码 ②托管代码编译为microsoft的平台专用语言,也叫机器代码

非托管代码:非托管代码是运行在公共语言运行库环境的外部,直接编译成目标计算机码,由操作系统直接执行的代码,代码必须自己提供垃圾回收,类型检查,安全支持等服务。如需要内存管理等服务,必须显示调用操作系统的接口,通常调用Windows SDK所提供的API来实现内存管理。

一般可以认为:非托管代码主要是基于win 32平台开发的DLL,activeX的组件,托管代码是基于.net平台开发的。

托管代码和非托管代码的区别

1、托管代码是一种中间语言,运行在CLR上;非托管代码被编译为机器码,运行在机器上。

2、托管代码独立于平台和语言,能更好的实现不同语言平台之间的兼容;非托管代码依赖于平台和语言。

3、托管代码可享受CLR提供的服务(如安全检测、垃圾回收等),不需要自己完成这些操作;非托管代码需要自己提供安全检测、垃圾回收等操作。 

2.Dll文件的使用

DLL文件是动态链接库,也叫程序集,是一个包含可由多个程序,同时使用的代码和数据的库。

程序集是在 .NET 公共语言运行库 (CLR) 控制之下运行的逻辑功能单元。程序集实际上是作为 .dll 文件或 .exe 文件存在的。

托管代码生成的DLL文件,可以在VS中直接通过添加引用的方式使用。

非托管代码生成的DLL文件,比如使用C++编写的代码编译生成的DLL,不能在VS中直接引用,可以通过DllImport方法来使用。

3.DllImport的基本使用

DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出函数的必要调用信息。
DllImportAttribute属性用法定义如下:

[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 {…} }
}

 DllImportAttribute 属性:

CallingConvention:指示入口点的调用约定。如果未指定 CallingConvention,则使用默认值 CallingConvention.Winapi。
CharSet :指示用在入口点中的字符集。如果未指定 CharSet,则使用默认值 CharSet.Auto。
EntryPoint :给出 dll 中入口点的名称。如果未指定 EntryPoint,则使用方法本身的名称。
ExactSpelling:指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配。如果未指定 ExactSpelling,则使用默认值 false。
PreserveSig :指示方法的签名应当被保留还是被转换。当签名被转换时,它被转换为一个具有 HRESULT 返回值和该返回值的一个名为 retval 的附加输出参数的签名。如果未指PreserveSig,则使用默认值 true。
SetLastError :指示方法是否保留 Win32"上一错误"。如果未指定 SetLastError,则使用默认值 false。

(1)引入命名空间
using System.Runtime.InteropServices;
 (2)创建函数名称
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section,string key,string val,string filePath);
(3)注意事项:

1.DllImport属性应用于方法,要求最少要提供包含入口点的dll的名称。

2.修饰符static和extern是必不可少的(extern外部修饰符,常与DllImport属性一起使用,用于支持在外部实现方法)。

3.引入到C#中的只能是非托管dll中的方法(或者说函数),而不能是数据(或者说变量)

4.返回变量类型、方法名称、参数列表一定要与DLL文件中的定义相一致。若要使用其它函数名,可以使用EntryPoint属性设置,如:

[DllImport("user32.dll", EntryPoint="MessageBoxA")]
static extern int MsgBox(int hWnd, string msg, string caption, int type);

5.DLL文件必须位于程序当前目录或系统定义的查询路径中(即:系统环境变量中Path所设置的路径),DLLImport会按照顺序去查找DLL文件(程序当前目录>System32目录>环境变量Path所设置路径)。

引用路径如下:

  (1)exe运行程序所在的目录

  (2)System32目录

  (3)环境变量目录

  (4)自定义路径,如:DllImport(@"C:\OJ\Bin\Judge.dll")

标签:string,C#,DllImport,托管,public,DLL,方法,代码
From: https://blog.csdn.net/qq_41184334/article/details/140319922

相关文章

  • 【ComfyUI教程】超自然的AI 任意换脸!保姆级教程(附资料)
    嘿,说到拍照,咱们男生有时候也挺头疼的,尤其是帮女朋友或者老婆挑衣服的时候。你懂的,一不小心就可能踩雷,好心办坏事。但别担心,今天我要介绍的这个ComfyUI,简直就是咱们的救星!想象一下,你和女朋友或者老婆一起挑选艺术照的服装,用ComfyUI,你们可以先预览各种风格的搭配,看看哪一款最......
  • 《基于 LatentFactor + Redis + ES 实现动态药房分配方法》
    ......
  • Franka Robot cmake demo
    cmake_minimum_required(VERSION3.4)#指定CMake的最低版本要求为3.4project(libfranka-examplesCXX)#定义项目名称为libfranka-examples,并指定语言为C++list(INSERTCMAKE_MODULE_PATH0${CMAKE_CURRENT_LIST_DIR}/../cmake)#将父目录的`cmake`子目录添加到......
  • echarts——横坐标轴文字过长如何换行
    横坐标轴文字过长,想要换行实现如下效果具体实现代码如下:axisLabel:{show:true,interval:0,formatter:function(value){varret="";//拼接加\n返回的类目项varma......
  • 51单片机嵌入式开发:7、 STC89C52RC 外部中断INT0和INT1 操作
    STC89C52RC外部中断INT0和INT1操作1外部中断1.1外部中断1.2中断介绍2STC89C52外部中断2.1外部中断引脚2.2外部中断寄存器说明3STC89C52外部中断演示3.1电平触发外部中断3.2边沿触发外部中断3.3Protues仿真4外部中断总结1外部中断1.1外部中断单片......
  • Codeforces Round 954(Div. 3)
    CodeforcesRound954(Div.3)目录CodeforcesRound954(Div.3)\(C\).UpdateQueries\(D\).MathematicalProblem\(E\).BeautifulArray方法一:贪心+滑动窗口方法二:DP\(C\).UpdateQueries对索引数组\(ind\)去重排序对字符串\(c\)排序顺序遍历索引数组,将\(s[ind[i]......
  • 在Linux中,怎么把脚本添加到系统服务里,即用 service 来调用?
    在Linux中,将脚本添加为系统服务,使其可以通过service命令进行管理,通常涉及以下步骤:编写启动脚本:创建一个启动脚本,该脚本将被Systemd或其他初始化系统用来启动、停止和重启你的应用程序或服务。例如,创建一个名为your_service的脚本,并赋予执行权限:#!/bin/bash#你的启动停止逻......
  • Linux: System call
    参考:https://blog.csdn.net/weixin_41028621/article/details/134542010?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-134542010-blog-130766392.235%5Ev43%5Epc_blog_bottom_relevance_ba......
  • Java中的SpringAOP、代理模式、常用AspectJ注解详解
      这篇文章主要介绍了Java中的SpringAOP、代理模式、常用AspectJ注解详解,Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务,例如审计和事务管理进行内聚性的开发,需要的朋友可以参考下 +目录一、AOP简述回到主题,何为AOP?AOP即面向切面编......
  • .Net Core WebApi项目 Development模式下报错 System.InvalidOperationException 解决
    .NetCoreWebApi项目Development模式下报错System.InvalidOperationException:“Cannotresolvescopedservice'Microsoft.Extensions.Options.IOptionsSnapshot`1[Infrastructure.OptionsSetting]'fromrootprovider.” 但是在Production模式下,运行正常因为未设置的......