DLLImport

namespace Wintellect.Interop.Sound
{
    using System;
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    sealed class Sound
    {
        public static void MessageBeep(BeepTypes type)
        {
            if(!MessageBeep((UInt32) type))
             {
                     Int32 err = Marshal.GetLastWin32Error();
                     throw new Win32Exception(err);
             }
        }

        [DllImport("User32.dll", SetLastError=true)]
        static extern Boolean MessageBeep(UInt32 beepType); 

        private Sound()
        {
        }
    } 

    enum BeepTypes{
         Simple = -1,
         Ok = 0x00000000,
         IconHand = 0x00000010,
         IconQuestion = 0x00000020,
         IconExclamation = 0x00000030,
         IconAsterisk = 0x00000040
         }
}

C 和 Win32 的一些公共数据类型及其规范,以及一个具有匹配规范的公共语言运行库类型

Win32 Types Specification CLR Type
char, INT8, SBYTE, CHAR† 8-bit signed integer System.SByte
short, short int, INT16, SHORT 16-bit signed integer System.Int16
int, long, long int, INT32, LONG32, BOOL†, INT 32-bit signed integer System.Int32
__int64, INT64, LONGLONG 64-bit signed integer System.Int64
unsigned char, UINT8, UCHAR†, BYTE 8-bit unsigned integer System.Byte
unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR†, __wchar_t 16-bit unsigned integer System.UInt16
unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT 32-bit unsigned integer System.UInt32
unsigned __int64, UINT64, DWORDLONG, ULONGLONG 64-bit unsigned integer System.UInt64
float, FLOAT Single-precision floating point System.Single
double, long double, DOUBLE Double-precision floating point System.Double
†In Win32 this type is an integer with a specially assigned meaning; in contrast, the CLR provides a specific type devoted to this meaning.

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

Calling Win32 DLLs in C# with P/Invoke

指针参数

指针增加了封送数据的复杂性,因为它们增加了一个间接层。使用托管代码表示此附加间接层的方式有多种。

FileEncryptionStatus API 函数

BOOL FileEncryptionStatus(
  LPCTSTR lpFileName,  // file name
  LPDWORD lpStatus     // encryption status
);

工作方式是调用程序向该函数传递指向一个 DWORD 变量的指针,而该 API 函数用状态值填充指向的内存位置。

调用非托管 FileEncryptionStatus 函数的可能外部方法定义:

[DllImport("Advapi32.dll", CharSet=CharSet.Auto)]
static extern Boolean FileEncryptionStatus(String filename, out UInt32 status);

该定义使用 out 关键字来为 UInt32 状态值指示 by-ref 参数。这里我也可以选择 ref 关键字,实际上在运行时会产生相同的机器码。out 关键字只是一个 by-ref 参数的规范,它向 C# 编译器指示所传递的数据只在被调用的函数外部传递。相反,如果使用 ref 关键字,则编译器会假定数据可以在被调用的函数的内部和外部传递。

(The definition uses the out keyword to indicate a by-ref parameter for the UInt32 status value. I could have selected the ref keyword here as well, and in fact both result in the same machine code at run time. The out keyword is simply a specialization of a by-ref parameter that indicates to the C# compiler that the data being passed is only being passed out of the called function. In contrast, with the ref keyword the compiler assumes that data may flow both in and out of the called function.)

封送不透明 (Opaque) 指针:一种特殊情况

当一个不透明指针返回给您的应用程序(或者您的应用程序期望得到一个不透明指针)时,您应该将参数或返回值封送为 CLR 中的一种特殊类型 — System.IntPtr。

请记住,任何返回或接受句柄的 API 函数其实操作的就是不透明指针。您的代码应该将 Windows 中的句柄封送成 System.IntPtr 值。

当使用 Windows API 函数时,因为指针应是不透明的,所以除了存储和传递给外部方法外,不能将它们另做它用。

这种“只限存储和传递”规则的两个特例是当您需要向外部方法传递 null 指针值和需要比较 IntPtr 值与 null 值的情况。为了做到这一点,您不能将零强制转换为 System.IntPtr,而应该在 IntPtr 类型上使用 Int32.Zero 静态公共字段,以便获得用于比较或赋值的 null 值。

封送文本

  • 是您的应用程序向 API 函数传递文本数据,还是 API 函数向您的应用程序返回字符串数据?或者二者兼有?
  • 您的外部方法应该使用什么托管类型?
  • API 函数期望得到的是什么格式的非托管字符串?
UINT_PTR SHAppBarMessage(
  _In_     DWORD dwMessage,
  _Inout_  PAPPBARDATA pData
);
typedef struct _AppBarData {
  DWORD  cbSize;
  HWND   hWnd;
  UINT   uCallbackMessage;
  UINT   uEdge;
  RECT   rc;
  LPARAM lParam;
} APPBARDATA, *PAPPBARDATA;
typedef struct _RECT {
  LONG left;
  LONG top;
  LONG right;
  LONG bottom;
} RECT, *PRECT;
struct AppBarData
    {
        public UInt32 cbSize;

        public IntPtr hWnd;

        public UInt32 uCallbackMessage;

        public UInt32 uEdge;

        public AppBarRect rc;

        public IntPtr lParam;
    }

    struct AppBarRect
    {
        public Int32 left;

        public Int32 top;

        public Int32 right;

        public Int32 bottom;
    }

DLLImport,布布扣,bubuko.com

时间: 2024-11-10 01:22:07

DLLImport的相关文章

DllImport 自动选择x64或x86 dll

前言 标题不知道怎么确切地命名,在.net的托管世界里,有时不得不使用c的某个动态库,比如ocr.opencv等,如果幸运,有前人已经包装出.net版本,但有些不非常流行的库,只能自己使用pinvoke或c++ cli包装了,比如笔者就遇到了一个,mqtt客户端库. Pinvoke的多平台问题 如果您没有接触过如何调用非托管dll,没有了解过c#的DllImportAttribute,可以看看以下资料: 1.DllImportAttribute 2.Pinvoke 3.extern 关键字 多平

C# DllImport“调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 ”

调用外部dll时,出现如下问题 C# DllImport“调用导致堆栈不对称.原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配.请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 ” 后来经过仔细检查发现,误把vb中的longx型当成64位,实际上它相当于C#中的32位int型.

C# 64位win7下DllImport LoadLibrary函数失败 z

[DllImport["kernel32.dll"]] static extern IntPtr LoadLibrary(string lpFileName); public void Fun() { IntPtr p = LoadLibrary(abc.dll); } 在32位xp系统下正常,可在64位windows 7系统下,p值返回为0 abc.dll可在mfc程序里用loadlibrary正常调用.并不缺少任何其他相关dll. ***** 把winform程序编译成x86的目标

浅谈__declspec(dllexport)和__declspec(dllimport)

__declspec(dllimport)和__declspec(dllexport)经常是成对的,在动态链接库中__declspec(dllexport)导出dll中的成员,__declspec(dllimport)导入外部dll中的成员. 但是有时候不使用dllimport和dllexport也能实现个基本的导出导入功能, 它们具有的功能如下: 1.dllimport/dllexport可以导入或者导出动态链接库中的全局变量,当然是用extern也可以实现同样的功能: 2.dllimport

C#中DllImport用法汇总

(转) 最近使用DllImport,从网上google后发现,大部分内容都是相同,又从MSDN中搜集下,现将内容汇总,与大家分享. 大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法)要重新编写代码,C#有没有方法可以直接都用这些原本已经存在的功能呢?答案是肯定的,大家可以通过C#中的DllImport直接调用这些功能. DllImport是System.Runtime.InteropServices命名空间下的

使用 DllImport 属性

本主题说明 DllImport 属性的常见用法.第一节讨论使用 DllImport 从托管应用程序调用本机代码的优点.第二节集中讨论封送处理和 DllImport 属性的各个方面. 从托管应用程序调用非托管代码 当在托管应用程序中重用现有的非托管代码时,DllImport 属性非常有用.例如,托管应用程序可能需要调用非托管 WIN32 API. 下面的代码示例说明此通用方案,此示例将调用 MessageBox(位于 User32.lib 中): #using <mscorlib.dll> us

[转]从普通DLL中导出C++类 – dllexport和dllimport的使用方法(中英对照、附注解)

这几天写几个小程序练手,在准备将一个类导出时,发现还真不知道如果不用MFC的扩展DLL,是怎么导出的.但我知道dllexport可以导出函数和变量,而且MFC扩展DLL就算是使用了MFC的功能,但能否导出类应该也不是必须用MFC才能够做到,一定是有相应的机制可以实现.于是查了一下MSDN,发现这个机制简单的可怕,原来就和导出函数一样,把dllexport关键字加到类名前就可以了.估计和我一样的同学大有人在,把MSDN的相关文档翻译出来,附上我的注解,希望对大家有用. 评注程序均在Visual S

__declspec(dllimport)与__declspec(dllexport)作用总结

参考自:http://bbs.csdn.net/topics/330169671 __declspec(dllexport):导出符号,也就是定义需要导出函数的dll中给导出函数的函数声明前面加上导出符号,表示该方法可以导出给其他DLL或者exe使用: __declspec(dllimport)导入符号,也就是在使用该函数的DLL或者exe中需要在该函数的函数声明前面加上该符号,表示该函数方法是从其他库导入的. 我们编写一个DLL库一般都是用来给其他DLL或者exe程序调用的.当我们编写DLL库

.net 中的DllImport

只有做成COM的C++ dll才能直接引用.没有做成COM的就只能用P/Invoke(DllImport)或者C++/CLI那种.不过P/Invoke容易类型对不上,所以要是函数多,最好用C++/CLI的. --------------------------------------------- C++ dll 分两种,文章描述有误.文章所述是静态dll,动态dll是可以直接引用的 ------------------------------------------------- VC++中主

【转帖】C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用

1      DLLImport的使用 using System; using System.Runtime.InteropServices; //命名空间 class Example { //用DllImport 导入Win32的MessageBox函数 [DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern int MessageBox(IntPtr hWnd, String text, S