当前位置: 首页 > news >正文

回答网友问题:在C# 中调用非托管DLL

在一个QQ群里,有人在问如何“在C# 中调用非托管DLL”。

俺脑子抽抽了一下,就回了一句“你喜欢用那种声明方式,就用那种方式去调用。”

然后就有人说:“参数声明要和DLL的声明完全一致”。

俺脑子又抽抽了一下,又回了一句“可以不一致,反正就是两种 一种是byref 一种是byval。注意一些,这个就OK”。

然后就被怼了。俺就写了一个例子,用三种不同的声明方式进行演示,发在了群里。然后俺就被 踢出群了。

下面的代码中:

第一种声明方式 : private static extern uint GetWindowsDirectoryA(StringBuilder lpBuffer, uint  uSize ) ; 这种方式用的比较多,也是 大家推荐的一种写法。

第二种声明方式: private static extern uint GetWindowsDirectoryA_ref( ref byte lpBuffer, uint uSize); 这个其实就个bug。但是它确实可以得到正确的结果。虽然参数声明中 的  ref byte lpBuffer 是错误的,但是这不妨碍执行结果的正确。

第三种方式:private static extern uint GetWindowsDirectoryA_IntPtr(IntPtr lpBuffer, uint uSize);这种方式比较原始,但是俺喜欢这种方式。如果一定要给个理由的话,那就是情怀。

  public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){}//function GetWindowsDirectoryA(lpBuffer: PAnsiChar; uSize: UINT): UINT; stdcall;//[DllImport("kernel32.dll", EntryPoint = "GetWindowsDirectoryA", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall) ]private static extern uint GetWindowsDirectoryA(StringBuilder lpBuffer, uint  uSize ) ;private void button1_Click(object sender, EventArgs e){StringBuilder sb = new StringBuilder();GetWindowsDirectoryA(sb, 255);MessageBox.Show(sb.ToString());}//[DllImport("kernel32.dll", EntryPoint = "GetWindowsDirectoryA", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]private static extern uint GetWindowsDirectoryA_ref( ref byte lpBuffer, uint uSize);private void button2_Click(object sender, EventArgs e){byte[] lpBuffer = new byte[255];uint c= GetWindowsDirectoryA_ref(ref lpBuffer[0], (uint)lpBuffer.Length); MessageBox.Show(Encoding.GetEncoding("gb2312").GetString(lpBuffer, 0, (int)c));//此方法不稳定}//[DllImport("kernel32.dll", EntryPoint = "GetWindowsDirectoryA", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]private static extern uint GetWindowsDirectoryA_IntPtr(IntPtr lpBuffer, uint uSize);private void button3_Click(object sender, EventArgs e){IntPtr ptr = Marshal.AllocHGlobal(255);uint c = GetWindowsDirectoryA_IntPtr(ptr,255);byte[] lpBuffer = new byte[c];Marshal.Copy(ptr,   lpBuffer,0,(int)c);MessageBox.Show(Encoding.GetEncoding("gb2312").GetString(lpBuffer, 0, (int)c));Marshal.FreeHGlobal(ptr);}}

相关文章:

  • 基于Spring 框架中的@Async 注解实现异步任务
  • Spring Aware接口:揭秘Bean生命周期中的“先知”角色与源码剖析
  • 第十三届蓝桥杯国赛大学B组填空题(c++)
  • window安装ffmpeg播放本地摄像头视频
  • Java面试进阶指南:高级知识点问答精粹(一)
  • Gitlab不允许使用ssh拉取代码的解决方案
  • 【NVM】持久内存的架构
  • vue3中element-plus下拉菜单与图标的使用
  • 22-LINUX--多线程and多进程TCP连接
  • 字节跳动(校招)算法原题
  • SQL生成序列浅析
  • Linux-用户管理
  • 【RabbitMQ】使用SpringAMQP的Publish/Subscribe(发布/订阅)
  • 【大模型部署】在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型
  • Hive环境搭建
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • angular组件开发
  • CSS居中完全指南——构建CSS居中决策树
  • css系列之关于字体的事
  • nginx 负载服务器优化
  • PAT A1120
  • python 装饰器(一)
  • Vue官网教程学习过程中值得记录的一些事情
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 基于 Babel 的 npm 包最小化设置
  • 简单基于spring的redis配置(单机和集群模式)
  • 如何编写一个可升级的智能合约
  • 如何设计一个微型分布式架构?
  • 深度学习中的信息论知识详解
  • 使用 @font-face
  • 智能网联汽车信息安全
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类的类构造函数)
  • (Oracle)SQL优化技巧(一):分页查询
  • (vue)页面文件上传获取:action地址
  • (第二周)效能测试
  • (二十三)Flask之高频面试点
  • (顺序)容器的好伴侣 --- 容器适配器
  • (四)linux文件内容查看
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • ***检测工具之RKHunter AIDE
  • . NET自动找可写目录
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .NET 5种线程安全集合
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .NET HttpWebRequest、WebClient、HttpClient
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .Net Winform开发笔记(一)
  • .net 反编译_.net反编译的相关问题
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .NetCore 如何动态路由
  • .NET关于 跳过SSL中遇到的问题
  • .NET性能优化(文摘)