• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > 从C#程序中调用非受管DLLs的方法

从C#程序中调用非受管DLLs的方法

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了dlls,missing dlls,vc80 support dlls,appinit dlls,can not find dlls等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文实例讲述了从C#程序中调用非受管DLLs的方法。分享给大家供大家参考。具体方法如下:

前言:

从所周知,.NET已经渐渐成为一种技术时尚,那么C#很自然也成为一种编程时尚。如何利用浩如烟海的Win32 API以及以前所编写的 Win32 代码已经成为越来越多的C#程序员所关注的问题。本文将介绍如何从C#代码中调用非受管DLLs。如果某个函数是一个带有串类型(char*)输出参数的Win32 API 或者是DLL输出函数,那么从C#中如何调用它呢?对于输入参数的情形问题到不大,但如何获取从参数中返回的串呢?此外,如何调用有结构(struct)和回调(callback)作为参数的函数,如GetWindowsRect 和EnumWindows?那我们又如何将参数从C++和MFC中转换成C# 所要的类型呢?下面就让我们来一一解决这些问题。

微软.NET的一个最主要的优势是它提供一个语言无关的开发系统。我们可以用Visual Basic、C++、C#等等语言来编写类,然后在其它语言中使用,我们甚至可以用不同的语言来派生类。但是如何调用以前开发的非受管DLL呢?方法是必须将.NET对象转化成结构、char*以及C语言的指针。用行话说就是参数必须被列集(marshal)。说到列集,用一两句话也说不清楚。所幸的是实现列集并不要我们知道太多的东西。

为了从C# 中调用DLL函数,首先必须要有一个声明,就象长期以来使用Visual Basic的程序员所做的那样,只不过在C#中使用的是DllImport关键字:

public class Win32 {
  [DllImport("User32.Dll")]
  public static extern void SetWindowText(int h, String s);
}</div>

在C#中,DllImport关键字作用是告诉编译器入口点在哪里,并将打包函数捆绑在一个类中。我们可以为这类取任何名字,这里不妨将类名取为 Win32。我们甚至可以将这个类放到一个名字空间中,就象下面的代码这样:

Win32API.cs 源代码

// 编译方法:
//    csc /t:library /out:Win32API.dll Win32API.cs
//
using System;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices;

/////////////////////////////////////////////////////////////////
// 包装Win32 API函数的名字空间。想用哪个Win32 API,往里添加即可。
//
namespace Win32API {
   [StructLayout(LayoutKind.Sequential)]
   public struct POINT {
      public POINT(int xx, int yy) { x=xx; y=yy; }
      public int x;
      public int y;
      public override string ToString() {
         String s = String.Format("({0},{1})", x, y);
         return s;
      }
   }

   [StructLayout(LayoutKind.Sequential)]
   public struct SIZE {
      public SIZE(int cxx, int cyy) { cx=cxx; cy=cyy; }
      public int cx;
      public int cy;
      public override string ToString() {
         String s = String.Format("({0},{1})", cx, cy);
         return s;
      }
   }

   [StructLayout(LayoutKind.Sequential)]
   public struct RECT {
      public int left;
      public int top;
      public int right;
      public int bottom;
      public int Width()      { return right - left; }
      public int Height()     { return bottom - top; }
      public POINT TopLeft()  { return new POINT(left,top); }
      public SIZE  Size()     { return new SIZE(Width(), Height()); }
      public override string ToString() {
         String s = String.Format("{0}x{1}", TopLeft(), Size());
         return s;
      }
   }

   public class Win32 {
      [DllImport("user32.dll")]
      public static extern bool IsWindowVisible(int hwnd);

      [DllImport("user32.dll")]
      public static extern int GetWindowText(int hwnd,
         StringBuilder buf, int nMaxCount);

      [DllImport("user32.dll")]
      public static extern int GetClassName(int hwnd,
         [MarshalAs(UnmanagedType.LPStr)] StringBuilder buf,
         int nMaxCount);

      [DllImport("user32.dll")]
      public static extern int GetWindowRect(int hwnd, ref RECT rc);

      [DllImport("user32.dll")]
      // 注意,运行时知道如何列集一个矩形
      public static extern int GetWindowRect(int hwnd, ref Rectangle rc);
   }
}</div>

用下面的命令行可以编译这段代码: csc /t:library /out:Win32API.dll Win32API.cs    
成功编译后,我们就有了一个可以在C#工程中使用的动态库了(Win32API.dll)。

int hwnd = // get it
String s = "I''''m so cute." ;
Win32.SetWindowText(hwnd, s);</div>
 
编译器知道在user32.dll中找到SetWindowText,并在调用前自动将串转换为LPTSTR (TCHAR*)。真是神奇!.NET是如何实现的呢?其实,每一个C#类型都有一个缺省的列集类型。对于串来说,它的列集类型就是LPTSTR。但如果调用的是GetWindowText,它的串参数是一个输出参数,而非输入参数,因为串是不变的,再象上面这样处理就行不通了。我们可能一点都没有注意到,不论什么时候处理一个串时,都会创建一个新串。要想修改这个串,必须用StringBuilder:

public class Win32 {
  [DllImport("user32.dll")]
  public static extern int GetWindowText(int hwnd,
    StringBuilder buf, int nMaxCount);
}</div>

StringBuilder缺省的列集类型是LPTSTR,但是GetWindowText现在可以修改实际的串。

StringBuilder sb = new StringBuilder(256);
Win32.GetWindowText(hwnd, sb, sb.Capacity);</div>

所以我们第一个问题的答案就是:使用Strin

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 从C#程序中调用非受管DLLs的方法

相关文章

  • 2017-05-28在Parallel中使用DbSet.Add()发现的一系列多线程问题和解决思路详解
  • 2017-05-29DataAdapter.Fill指定条数记录,数据库返回全部记录还是返回所指定的记录条数?
  • 2017-05-28测试框架nunit之assertion断言使用详解
  • 2017-05-28C#使用自定义算法对数组进行反转操作的方法
  • 2017-05-28WinForm绘制圆角的方法
  • 2017-05-28C#多线程学习之(三)生产者和消费者用法分析
  • 2017-05-28C#利用XML创建Excel文档的实现方法
  • 2017-05-28C#调用Java方法实例详解
  • 2017-05-28C# Hook钩子实例代码 截取键盘输入
  • 2017-05-28C#常用目录文件操作类实例

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 利用Aspose.Word控件实现Word文档的操作
    • C#图像亮度调整的方法
    • 简介Winform中创建用户控件
    • 关于C#程序优化的五十种方法
    • 关于c#二叉树的实现
    • 使用递归算法求第30位数的值
    • C#枚举中的位运算权限分配浅谈
    • C#实现根据字节数截取字符串并加上省略号的方法
    • c# 动态加载dll文件,并实现调用其中的简单方法
    • C# 将透明图片的非透明区域转换成Region的实例代码

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有