C#调用API函数

PInvoke之C#调用动态链接库DLL_v2.0 简单做一下总结叭,通过上述所描述的从第一步如何创建一个DLL到如何通过C#去调用的一个简单实例,也应该能给正在查阅相关资料的你有所收获,也希望能给在这方面有所研究的你有一些相关的启发,同时也希望能给目前对这方面毫无了解的你有一个更进一步的学习。C#实现排序所耗时: 130msC实现排序所耗时:3ms在实现本案例中,可能在编译后,大家所看到的结果不是很出乎意料,但这只是一种案例,希望通过此案例的分析,能给大家带来一些意想不到的收获叭。 阅读详情

Api函数是构筑Windws应用程序的基石,每一种Windows应用程序开发工具,它提供的底层函数都间接或直接地调用了Windows API函数,同时为了实现功能扩展,一般也都提供了调用WindowsAPI函数的接口, 也就是说具备调用动态连接库的能力。Visual C#和其它开发工具一样也能够调用动态链接库的API函数。.NET框架本身提供了这样一种服务,允许受管辖的代码调用动态链接库中实现的非受管辖函数,包括操作系统提供的Windows API函数。它能够定位和调用输出函数,根据需要,组织其各个参数(整型、字符串类型、数组、和结构等等)跨越互操作边界。

下面以C#为例简单介绍调用API的基本过程:
动态链接库函数的声明
 动态链接库函数使用前必须声明,相对于VB,C#函数声明显得更加罗嗦,前者通过 Api Viewer粘贴以后,可以直接使用,而后者则需要对参数作些额外的变化工作。

 动态链接库函数声明部分一般由下列两部分组成,一是函数名或索引号,二是动态链接库的文件名。
  譬如,你想调用User32.DLL中的MessageBox函数,我们必须指明函数的名字MessageBoxA或MessageBoxW,以及库名字User32.dll,我们知道Win32 API对每一个涉及字符串和字符的函数一般都存在两个版本,单字节字符的ANSI版本和双字节字符的UNICODE版本。

 下面是一个调用API函数的例子:
[DllImport("KERNEL32.DLL", EntryPoint="MoveFileW", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern bool MoveFile(String src, String dst);

 其中入口点EntryPoint标识函数在动态链接库的入口位置,在一个受管辖的工程中,目标函数的原始名字和序号入口点不仅标识一个跨越互操作界限的函数。而且,你还可以把这个入口点映射为一个不同的名字,也就是对函数进行重命名。重命名可以给调用函数带来种种便利,通过重命名,一方面我们不用为函数的大小写伤透脑筋,同时它也可以保证与已有的命名规则保持一致,允许带有不同参数类型的函数共存,更重要的是它简化了对ANSI和Unicode版本的调用。CharSet用于标识函数调用所采用的是Unicode或是ANSI版本,ExactSpelling=false将告诉编译器,让编译器决定使用Unicode或者是Ansi版本。其它的参数请参考MSDN在线帮助.

 在C#中,你可以在EntryPoint域通过名字和序号声明一个动态链接库函数,如果在方法定义中使用的函数名与DLL入口点相同,你不需要在EntryPoint域显示声明函数。否则,你必须使用下列属性格式指示一个名字和序号。

[DllImport("dllname", EntryPoint="Functionname")]
[DllImport("dllname", EntryPoint="#123")]
值得注意的是,你必须在数字序号前加“#”
下面是一个用MsgBox替换MessageBox名字的例子:
[C#]
using System.Runtime.InteropServices;

public class Win32 {
[DllImport("user32.dll", EntryPoint="MessageBox")]
public static extern int MsgBox(int hWnd, String text, String caption, uint type);
}
许多受管辖的动态链接库函数期望你能够传递一个复杂的参数类型给函数,譬如一个用户定义的结构类型成员或者受管辖代码定义的一个类成员,这时你必须提供额外的信息格式化这个类型,以保持参数原有的布局和对齐。

C#提供了一个StructLayoutAttribute类,通过它你可以定义自己的格式化类型,在受管辖代码中,格式化类型是一个用StructLayoutAttribute说明的结构或类成员,通过它能够保证其内部成员预期的布局信息。布局的选项共有三种:

布局选项
描述
LayoutKind.Automatic
为了提高效率允许运行态对类型成员重新排序。
注意:永远不要使用这个选项来调用不受管辖的动态链接库函数。
LayoutKind.Explicit
对每个域按照FieldOffset属性对类型成员排序
LayoutKind.Sequential
对出现在受管辖类型定义地方的不受管辖内存中的类型成员进行排序。
传递结构成员
下面的例子说明如何在受管辖代码中定义一个点和矩形类型,并作为一个参数传递给User32.dll库中的PtInRect函数,
函数的不受管辖原型声明如下:
BOOL PtInRect(const RECT *lprc, POINT pt);
注意你必须通过引用传递Rect结构参数,因为函数需要一个Rect的结构指针。
[C#]
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 Win32API {
[DllImport("User32.dll")]
public static extern Bool PtInRect(ref Rect r, Point p);
}
类似你可以调用GetSystemInfo函数获得系统信息:
? using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_INFO {
public uint dwOemId;
public uint dwPageSize;
public uint lpMinimumApplicationAddress;
public uint lpMaximumApplicationAddress;
public uint dwActiveProcessorMask;
public uint dwNumberOfProcessors;
public uint dwProcessorType;
public uint dwAllocationGranularity;
public uint dwProcessorLevel;
public uint dwProcessorRevision;
}


[DllImport("kernel32")]
static extern void GetSystemInfo(ref SYSTEM_INFO pSI);

SYSTEM_INFO pSI = new SYSTEM_INFO();
GetSystemInfo(ref pSI);

类成员的传递
同样只要类具有一个固定的类成员布局,你也可以传递一个类成员给一个不受管辖的动态链接库函数,下面的例子主要说明如何传递一个sequential顺序定义的MySystemTime类给User32.dll的GetSystemTime函数, 函数用C/C++调用规范如下:

void GetSystemTime(SYSTEMTIME* SystemTime);
不像传值类型,类总是通过引用传递参数.
[C#]
[StructLayout(LayoutKind.Sequential)]
public class MySystemTime {
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
class Win32API {
[DllImport("User32.dll")]
public static extern void GetSystemTime(MySystemTime st);
}
回调函数的传递:
从受管辖的代码中调用大多数动态链接库函数,你只需创建一个受管辖的函数定义,然后调用它即可,这个过程非常直接。
如果一个动态链接库函数需要一个函数指针作为参数,你还需要做以下几步:
首先,你必须参考有关这个函数的文档,确定这个函数是否需要一个回调;第二,你必须在受管辖代码中创建一个回调函数;最后,你可以把指向这个函数的指针作为一个参数创递给DLL函数,.

回调函数及其实现:
回调函数经常用在任务需要重复执行的场合,譬如用于枚举函数,譬如Win32 API 中的EnumFontFamilies(字体枚举), EnumPrinters(打印机), EnumWindows (窗口枚举)函数. 下面以窗口枚举为例,谈谈如何通过调用EnumWindow 函数遍历系统中存在的所有窗口

分下面几个步骤:
1. 在实现调用前先参考函数的声明
BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARMAM IParam)
显然这个函数需要一个回调函数地址作为参数.
2. 创建一个受管辖的回调函数,这个例子声明为代表类型(delegate),也就是我们所说的回调,它带有两个参数hwnd和lparam,第一个参数是一个窗口句柄,第二个参数由应用程序定义,两个参数均为整形。

  当这个回调函数返回一个非零值时,标示执行成功,零则暗示失败,这个例子总是返回True值,以便持续枚举。
3. 最后创建以代表对象(delegate),并把它作为一个参数传递给EnumWindows 函数,平台会自动地 把代表转化成函数能够识别的回调格式。

[C#]
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("窗口句柄为");
Console.WriteLine(hwnd);
return true;
}
}

指针类型参数传递:
 在Windows API函数调用时,大部分函数采用指针传递参数,对一个结构变量指针,我们除了使用上面的类和结构方法传递参数之外,我们有时还可以采用数组传递参数。

 下面这个函数通过调用GetUserName获得用户名
BOOL GetUserName(
LPTSTR lpBuffer, // 用户名缓冲区
LPDWORD nSize // 存放缓冲区大小的地址指针
);
 
[DllImport("Advapi32.dll",
EntryPoint="GetComputerName",
ExactSpelling=false,
SetLastError=true)]
static extern bool GetComputerName (
[MarshalAs(UnmanagedType.LPArray)] byte[] lpBuffer,
  [MarshalAs(UnmanagedType.LPArray)] Int32[] nSize );
 这个函数接受两个参数,char * 和int *,因为你必须分配一个字符串缓冲区以接受字符串指针,你可以使用String类代替这个参数类型,当然你还可以声明一个字节数组传递ANSI字符串,同样你也可以声明一个只有一个元素的长整型数组,使用数组名作为第二个参数。上面的函数可以调用如下:

byte[] str=new byte[20];
Int32[] len=new Int32[1];
len[0]=20;
GetComputerName (str,len);
MessageBox.Show(System.Text.Encoding.ASCII.GetString(str));
 最后需要提醒的是,每一种方法使用前必须在文件头加上:
 using System.Runtime.InteropServices;

C#调用Win32 的API函数--User32.dll Win32的API函数是微软自己的东西,可以直接在C#中直接调用,在做WinForm时还是很有帮助的。有时候我们之直接调用Win32 的API,可以很高效的实现想要的效果。CodeCode highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->using 阅读详情

相关推荐

C#-调用Windows API函数

调用Windows API函数请先参考"struct实例字段的内存布局(Layout)和大小(Size)"        Api函数是构筑Windws应用程序的基石,每一种Windows应用程序开发工具,它提供的底层函数都间接或直接地调用了Windows API函数,同时为了实现功能扩展,一般也都提供了调用WindowsAPI函数的接口, 也就是说具备调用动态连接库的能力。Visual C#和

MasterFT的专栏 1870

用Visual C#调用Windows API函数(转)

Api函数是构筑Windws应用程序的基石,每一种Windows应用程序开发工具,它提供的底层函数都间接或直接地调用了Windows API函数,同时为了实现功能扩展,一般也都提供了调用WindowsAPI函数的接口, 也就是说具备调用动态连接库的能力。Visual C#和其它开发工具一样也能够调用动态链接库的API函数。.NET框架本身提供了这样一种服务,允许受管辖的代码调用动态链接库中实现的非

闪电侠的家园 2050

用Visual C#调用Windows API函数

Api函数是构筑Windws应用程序的基石,每一种Windows应用程序开发工具,它提供的底层函数都间接或直接地调用了Windows API函数,同时为了实现功能扩展,一般也都提供了调用WindowsAPI函数的接口, 也就是说具备调用动态连接库的能力。Visual C#和其它开发工具一样也能够调用动态链接库的API函数。.NET框架本身提供了这样一种服务,允许受管辖的代码调用动态链接库中实现

lyxcyp的专栏 742

C# 调用 dll 文件

一、先使用C++来创建一个 .dll 文件 1、创建新项目:CreateDll01 2、选择 “动态链接库(.dll)” 文件 3、在CreateDll01.cpp 源文件中添加如下代码 // CreateDll01.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" extern "C" __declspec(dllex...

Jeffxu_lib的博客 2万+

C#中动态调用API函数

using System.Runtime.InteropServices; internal delegate bool Delegate_Beep(uint dwFreq, uint dwDuration);[DllImport("kernel32.dll")]internal static extern IntPtr LoadLibrary(string lpLibFile

伴水之剑 1817

打印机windows平台下API接口,含VB/VC/c#/Delphi工程案例

打印机windows平台下API接口,含VB/VC/c#/Delphi工程案例

C#中调用API函数方法

转:https://wenku.baidu.com/view/604cb5ae524de518964b7de6.html C#自身提供了非常强大的库,通过Object Browser可以进行查看,但是仍然有许多功能,需要使用API函数才能实现,C#中,通过调用系统DLL,并填写好接口,就可以使用各个API函数 ...

以梦为马 不负韶华 4950

机械臂电机力矩计算

设计 6 轴机械臂时,电机力矩计算是确保机械臂负载能力、运动精度和安全性的核心环节,需围绕和两大核心展开,结合机械臂结构参数(如关节长度、质量分布)、负载需求(如末端负载重量、惯性)和运动参数(如加速度、角速度)逐步推导。

ZPC8210的博客 1856

在C#中调用windows API函数

                   在C#中调用windows API函数 对于windows 系统API函数的调用在程序设计中有时是必不可少的,各种编程语言都规范了调用的方法和接口,在C#语言中的调用方法如下(以下编程环境为Visual Studio .NET):1、  在工程项目中添加一个类新项,打开这个类文件,在文件头部加入对以下命名空间的引用:     using Syste

zhoujunzs的专栏 1925

从零到一:STM32 CubeMX与WS2812B的DMA驱动艺术

本文详细介绍了如何使用STM32 CubeMX和DMA技术驱动WS2812B RGB LED灯条,从硬件设计到软件实现的全过程。通过CubeMX配置定时器和DMA,实现高效的PWM波形生成与数据传输,解决传统GPIO控制资源占用高的问题。文章还提供了颜色编码、动画效果实现及常见问题解决方案,助力开发者快速掌握智能LED控制技术。

weixin_28278377的博客 977

320x240 TFT屏的SPI DMA驱动避坑指南:基于HC32F460的时序调试心得

本文详细介绍了基于HC32F460 MCU驱动320x240 TFT屏的SPI DMA实战经验,涵盖硬件设计、波形诊断、DMA优化及高级调试技巧。重点解析SPI时序配置、DMA缓冲区对齐等常见问题,并提供逻辑分析仪波形诊断方法和性能优化策略,帮助开发者规避典型陷阱,提升显示性能。

weixin_42639246的博客 370

C#中正确的调用API函数

在C#中经常需要调用一些API函数,那么怎样才能正确的调用API函数呢,如下:   一、调用API格式   //引用此名称空间,简化后面的代码 usingSystem.Runtime.InteropServices; ...   //使用DllImportAttribute特性来引入api函数,注意声明的是空方法,即方法体为空。 [DllImport("user32.dll")]...

gtts 313

MAS1102量产工具实战指南:从下载到开卡,附固件选择与RDT优化技巧

本文提供MAS1102量产工具的实战指南,涵盖从工具下载、短接识别到开卡操作的全过程。重点解析了固件选择策略与RDT优化技巧,帮助用户成功修复基于联芸MAS1102主控的固态硬盘,解决常见开卡错误并提升SSD性能与稳定性。

c2d3e4f的博客 2191

C#调用Windows API函数

Api函数是构筑Windws应用程序的基石,每一种Windows应用程序开发工具,它提供的底层函数都间接或直接地调用了Windows API函数,同时为了实现功能扩展,一般也都提供了调用WindowsAPI函数的接口, 也就是说具备调用动态连接库的能力。Visual C#和其它开发工具一样也能够调用动态链接库的API函数。.NET框架本身提供了这样一种服务,允许受管辖的代码调用动态链接库中实现的非

a3676212的专栏 712

Obsidian笔记同步实战:基于Git的私有化部署与自动化管理

本文详细介绍了如何利用Git为Obsidian笔记构建私有化、自动化且免费的同步方案。通过安装配置Git与Obsidian-git插件,结合Gitee等远程仓库,实现笔记的版本管理、多设备同步与自动备份,打造安全可靠的知识管理体系。

y7z8a的博客 272

LeetCode 热题 100 回顾

力扣最受刷题发烧友欢迎的 100 道题 LeetCode 热题 100 : 题目回顾、解题思路、复杂度分析、代码实现、验证算法

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 9万+

C#中调用WIN32API函数

http://www.pinvoke.net/   磐实文章站(首页)首页 >Visual Basic软件开发资料 > API 函数 http://www.panshsoft.com/Sort_VB/API_fun/   GetWindowRect用法 http://blog.youkuaiyun.com/coolszy/article/details/5601455 函数功能:该函数返

jiangxinyu的专栏 2万+

CVPR 2026 即插即用 | 注意力篇 | PFG:多尺度大核+像素级频率门控,特征显著增强,精准适配边缘纹理场景

本文提出了一种基于频率引导的轻量级外围门控模块PFG,用于高效时空预测学习。该模块通过多尺度大核分解卷积(1×K + K×1)捕捉外围空间依赖,同时利用固定频率滤波器提取高频线索,动态融合不同尺度的外围特征。核心创新包括:外围聚焦的多尺度空间增强、频率引导的动态融合机制、双阶段归一化协同等。实验表明,PFGNet在多个基准数据集上达到SOTA性能,同时保持较低计算复杂度。该模块可直接嵌入各类视觉模型,适用于需要强化空间-通道协同表达的轻量级任务。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 477

c#调用Win32 Api函数

在c#中可以通过互操作性服务using System.Runtime.InteropServices来调用window api函数.并且通过属性来指定api函数的位置,以及调用方式,比如,我们要调用User32.dll里的函数MessageBox(HWnd hwnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT type)首先引入名字空间using System.Ru

Glacial Zone 585

Python自动化脚本:模拟鼠标键盘保持电脑在线状态

在计算机自动化领域,模拟用户输入是一项基础且实用的技术,其核心原理是通过程序生成鼠标或键盘事件来与操作系统交互。这项技术的价值在于能够自动化重复性操作,提升工作效率,并解决特定场景下的系统交互问题。PyAutoGUI作为Python生态中广泛使用的自动化库,封装了跨平台的底层API调用,为开发者提供了简洁统一的接口来实现输入模拟。在实际工程实践中,这类技术常应用于自动化测试、远程办公辅助、数据抓取等场景,帮助用户保持系统活跃状态,防止因无操作导致的锁屏或休眠中断任务。通过合理配置移动间隔和随机化模式,可以更

weixin_28713299的博客 577

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C#调用user32.dll Win32的API函数

C#调用user32.dll Win32的API函数 usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Runtime.InteropServices; namespaceWindowsA...

cxu123321的博客 537

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

上一篇: C# win32 API编程
下一篇: C#中调用Windows API的要点
nodeadbird520
博客等级 码龄19年 20粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值