C#调用dll时的类型转换总结


C++(Win 32)


C#


char**


作为输入参数转为char[],通过Encoding类对这个string[]进行编码后得到的一个char[]


作为输出参数转为byte[],通过Encoding类对这个byte[]进行解码,得到字符串


C++ Dll接口:

void CplusplusToCsharp(in char** AgentID, out char** AgentIP);

C#中的声明:

[DllImport("Example.dll")]

public static extern void CplusplusToCsharp(char[] AgentID, byte[] AgentIP);

C#中的调用:

Encoding encode = Encoding.Default;

byte[] tAgentID;

byte[] tAgentIP;

string[] AgentIP;

tAgentID = new byte[100];

tAgentIP = new byte[100];

CplusplusToCsharp(encode.GetChars(tAgentID), tAgentIP);

AgentIP[i] = encode.GetString(tAgentIP,i*Length,Length);


Handle


IntPtr


Hwnd


IntPtr


int*


ref int


int&


ref int


void*


IntPtr


unsigned char*


ref byte


BOOL


bool


DWORD


int 或 uint(int 更常用一些)


枚举类型


Win32:

BOOL MessageBeep(UINT uType // 声音类型); 其中的声音类型为枚举类型中的某一值。

C#:

用户需要自己定义一个枚举类型:

public enum BeepType

{

  SimpleBeep = -1,

  IconAsterisk = 0x00000040,

  IconExclamation = 0x00000030,

  IconHand = 0x00000010,

  IconQuestion = 0x00000020,

  Ok = 0x00000000,

}

C#中导入该函数:

[DllImport("user32.dll")]

public static extern bool MessageBeep(BeepType beepType);

C#中调用该函数:

MessageBeep(BeepType.IconQuestion);


结构类型


Win32:

使用结构指针作为参数的函数:

BOOL GetSystemPowerStatus(

 LPSYSTEM_POWER_STATUS lpSystemPowerStatus

);

Win32中该结构体的定义:

typedef struct _SYSTEM_POWER_STATUS {

BYTE  ACLineStatus;

BYTE  BatteryFlag;

BYTE  BatteryLifePercent;

BYTE  Reserved1;

DWORD BatteryLifeTime;

DWORD BatteryFullLifeTime;

} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;

C#:

用户自定义相应的结构体:

struct SystemPowerStatus

{

  byte ACLineStatus;

  byte batteryFlag;

  byte batteryLifePercent;

  byte reserved1;

  int batteryLifeTime;

  int batteryFullLifeTime;

}

C#中导入该函数:

[DllImport("kernel32.dll")]

public static extern bool GetSystemPowerStatus(

  ref SystemPowerStatus systemPowerStatus);

C#中调用该函数:

SystemPowerStatus sps;

….sps初始化赋值……

GetSystemPowerStatus(ref sps);


字符串


对于字符串的处理分为以下几种情况:

1、  字符串常量指针的处理(LPCTSTR),也适应于字符串常量的处理,.net中的string类型是不可变的类型。

2、  字符串缓冲区的处理(char*),即对于变长字符串的处理,.net中StringBuilder可用作缓冲区

Win32:

BOOL GetFile(LPCTSTR lpRootPathName);

C#:

函数声明:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]

static extern bool GetFile (

 [MarshalAs(UnmanagedType.LPTStr)]

 string rootPathName);

函数调用:

string pathname;

GetFile(pathname);

备注:

DllImport中的CharSet是为了说明自动地调用该函数相关的Ansi版本或者Unicode版本

变长字符串处理:

C#:

函数声明:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]

public static extern int GetShortPathName(

  [MarshalAs(UnmanagedType.LPTStr)]

  string path,

  [MarshalAs(UnmanagedType.LPTStr)]

  StringBuilder shortPath,

  int shortPathLength);

函数调用:

StringBuilder shortPath = new StringBuilder(80);

int result = GetShortPathName(

@"d:\test.jpg", shortPath, shortPath.Capacity);

string s = shortPath.ToString();


struct


具有内嵌字符数组的结构:

Win32:

typedef struct _TIME_ZONE_INFORMATION {

  LONG    Bias;

  WCHAR   StandardName[ 32 ];

  SYSTEMTIME StandardDate;

  LONG    StandardBias;

  WCHAR   DaylightName[ 32 ];

  SYSTEMTIME DaylightDate;

  LONG    DaylightBias;

} TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION;

C#:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

struct TimeZoneInformation

{

  public int bias;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]

  public string standardName;

  SystemTime standardDate;

  public int standardBias;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]

  public string daylightName;

  SystemTime daylightDate;

  public int daylightBias;

}


具有回调的函数


Win32:

BOOL EnumDesktops(

 HWINSTA hwinsta,       // 窗口实例的句柄

 DESKTOPENUMPROC lpEnumFunc, // 回调函数

 LPARAM lParam        // 用于回调函数的值

);

回调函数DESKTOPENUMPROC的声明:

BOOL CALLBACK EnumDesktopProc(

 LPTSTR lpszDesktop, // 桌面名称

 LPARAM lParam    // 用户定义的值

);

C#:

将回调函数的声明转化为委托:

delegate bool EnumDesktopProc(

 [MarshalAs(UnmanagedType.LPTStr)]

  string desktopName,

  int lParam);

该函数在C#中的声明:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern bool EnumDesktops(
  IntPtr windowStation,
  EnumDesktopProc callback,
  int lParam);

该表对C#中调用win32函数,以及c++编写的dll时参数及返回值的转换做了一个小的总结,如果想进一步了解这方面内容的话,可以参照msdn中“互操作封送处理”一节。

原文地址:https://www.cnblogs.com/endv/p/8351137.html

时间: 2024-10-07 12:05:20

C#调用dll时的类型转换总结的相关文章

在VS2012中采用C++中调用DLL中的函数 (4)

这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天开始尝试调试DLL的文件调用,起初笔者在网络上找到了3片采用VSXXX版本进行调试的例子,相关的内容见本人Blog在C++中调用DLL中的函数(1)(2)(3) 但是问题出现了,上面讲述的步骤很详细但是在自己运行的时候却会出现错误,于是今天在使用google“vs2012 c++调用dll”时,发现了一篇MSDN上的指南:http://msdn.microsoft.com/zh-cn/library/m

在VS2012中采用C++中调用DLL中的函数(4)

转自:http://www.cnblogs.com/woshitianma/p/3683495.html 这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天开始尝试调试DLL的文件调用,起初笔者在网络上找到了3片采用VSXXX版本进行调试的例子,相关的内容见本人Blog在C++中调用DLL中的函数(1)(2)(3) 但是问题出现了,上面讲述的步骤很详细但是在自己运行的时候却会出现错误,于是今天在使用google"vs2012 c++调用dll"

VS2013环境生成和调用DLL动态链接库

创建动态库方法: 创建动态库是生成 .dll .lib 两个个文件 文件 -> 新建 -> 项目 -> win32控制台应用程序 项目名称:DLLGenerator 应用程序类型:DLL  附加选项:空项目 建立源文件dllgenerator.cpp(不需要主函数,只写你需要动态调用的函数) // 整数加法和乘法 int Add(int a, int b){ return a + b; } int Mul(int c, int d){ return c * d; } 建立头文dllgen

无法将类型为“Excel.ApplicationClass”的 COM 对象强制转换为接口类 型“Excel._Application”。此操作失败的原因是对 IID 为“{000208D5 -0000-0000-C000-000000000046}”的接口的 COM 组件调用 QueryInterface 因以下错误而失败: 加载类型库/DLL 时出错。 (异常来 自 HRESULT:

无法将类型为“Excel.ApplicationClass”的 COM 对象强制转换为接口类 型“Excel._Application”.此操作失败的原因是对 IID 为“{000208D5 -0000-0000-C000-000000000046}”的接口的 COM 组件调用 QueryInterface 因以下错误而失败: 加载类型库/DLL 时出错. (异常来 自 HRESULT:0x80029C4A (TYPE_E_CANTLOADLIBRARY)) 经过多般折腾,还是没什么更好的办法.

关于C# 调用 C dll时,抓获C的异常

最近一直被C# 调用native code时的内存错误,各种错误所困扰.而且在.net 4.0中非托管代码的异常不能被托管代码抓获,导致程序直接crash. 最终找到了.net 的方法.MSDN有关于expection 的详细解释. 1. 在.net 3.5中是可以抓取AccessViolationException这个C崩溃的异常的,因此可以尝试使用这个.net 3.5重新编译 2.在.net 4,4.5中可以尝试在app.config 文件中加上如下的配置, <configuration>

[学习记录]使用C#语言调用.dll(动态链接库)文件

不可全信 感谢各位博客教会了我很多,我也要写出来参与社区建设. 嘛不一定完全正确,想要可靠性比较高的同志建议买书,书中出处啥的比较详细,可靠性比较高. --------------------- 1.基本步骤 1.1 向项目中导入dll文件 1.2 阅读dll文件的使用手册 [ 和头文件(.H) ] 1.3 编写导入dll文件中方法的代码 1.4 编写读取dll中对应数据的代码(可能略) 1.5 写方法调用dll中方法并加以判断调用是否成功 1.6 在相关位置调用使用自己定义的调用方法 2.基本

Golang调用Dll案例

前言 在家办公已经两个多星期了,目前最大的困难就是网络很差.独自一个人用golang开发调用dll的驱动程序.本来就是半桶水的我,还在为等待打开一个页面而磨平了耐心.本想依葫芦画瓢把这个驱动做了.可网上找到的案例都是一些简单的调用dll.对于各种传参.获取返回值和一些常见错误的文章太少(可能因为网络不好一些优质文章还没有点开就被关掉了).今天ITDragon就做一个简单的葫,以广播驱动作为案例. 1.The specified module could not be found. 2.%1 is

C#如何静态调用C++中的方法(静态调用dll)

当我们想要在C#中使用C++项目的方法时,这个时候就可以通过调用C++项目的dll来实现,它有静态和动态调用两种方法. DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型.在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中.当我们执行某一个程序时,相应的DLL文件就会被调用.一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件

C++ 生成 dll 和调用 dll 的方法实例(转)

1)生成dll 建立两个文件 xxx.h , xxx.cpp xxx.h内容如下: #ifdef BUILD_XXX_DLL#define EXPORT __declspec(dllexport)#else#define EXPORT __declspec(dllimport)#endif extern "C"{EXPORT void example(void);... ...} xxx.cpp内容如下: #define BUILD_XXX_DLL#include "xxx.