在C#中使用C/C++写的DLL,以及数据转换大全

来源:互联网 发布:软件安装管理器 编辑:程序博客网 时间:2024/04/29 00:29

呵呵..,又到了我有想写点东西的时候了.最近在论坛老是看见有朋友问C/C++的程序如何在C#中使用?其实这是个很不错的想法.代码复用.不过托管程序如何使用非托管代码呢?想想看,很自然就联想到了DLL动态连接库把C/C++的代码编译成DLL,然后使用,这里我假设我的C/C++代码里包含一个函数,叫average(intav[])

申明如下:
extern "C" __declspec(dllexport) __cdeclint average(int *av);

实现嘛就更简单了
__declspec(dllexport) __cdeclint average(intav[])
{
int i=0;
int sum=0;
  while(av)
{
  sum+=av[i];
   i++;
}
return sum/i;
}//随手写的也许有点问题

好了不管那么多,让我们来看看C#的代码是如何实现的,我想你应该想的到是什么?猜猜看,OK,我想你至少能想到两个英文单词dll import,是的你猜对了DLLImport属性,就是它,看看它有些什么,我可以用到,MSDN是最好的选择.看见了吗是的,准确地说,DllImport属性具有下列行为:

它只能放置在方法声明上。

它具有单个定位参数:指定包含被导入方法的dll名称的dllName参数。

它具有五个命名参数:
 

CallingConvention参数指示入口点的调用约定。如果未指定CallingConvention,则使用默认值 
CallingConvention.Winapi。

CharSet参数指示用在入口点中的字符集。如果未指定CharSet,则使用默认值CharSet.Auto。

EntryPoint参数给出dll中入口点的名称。如果未指定EntryPoint,则使用方法本身的名称。

ExactSpelling参数指示EntryPoint是否必须与指示的入口点的拼写完全匹配。如果未指定 
ExactSpelling,则使用默认值 false。

PreserveSig参数指示方法的签名应当被保留还是被转换。当签名被转换时,它被转换为一个具有 
HRESULT 返回值和该返回值的一个名为retval的附加输出参数的签名。如果未指定PreserveSig,则使
用默认值 true。

SetLastError参数指示方法是否保留 Win32“上一错误”。如果未指定SetLastError,则使用默认值

false。

它是一次性属性类。

此外,用DllImport属性修饰的方法必须具有 extern 修饰符。

是的,上面就是MSDN原文内容.好了继续我们的例子,好了,先把我们上面的C代码编译成DLL

叫什么呢?那就叫MYDLLTest好了.

[DllImport("MYDLLTest.dll",EntryPoint="average",ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]
static extern int average(intav[]);

好了,该是你找个地方写一句的时候了

如:

int[5] i={1,2,3,4,5};
int j=average(i);


好了,你看到了,就是这样的,可是事实上并没有你想的那么简单.因为设计到很多问题

你看上面的例子中,int是在C#和C/C++中都有的,可是如果是char *呢?也许你会说string

可是你看在C/C++中这些都表示字符串(char*,or wchar_t*,or BSTR, ..)那我们该怎么办?

想想看,还有些什么?属性吗?是的,找找,对了我似乎想到一个单词.Marshal恩..记得它吗?

别告诉我,你会把它拼成马歇尔.哈哈..开个玩笑是列集.我们在MSDN上输入看看找到什么了?

是的MarshalAs.看看MSDN上说些什么?"指示应如何在托管代码和非托管代码之间封送数据"

哈哈.看来不错呢.在看看下面的备注:

可将该属性应用于参数、字段或返回值。

该属性为可选属性,因为每个数据类型都有默认的封送处理行为。仅在可以将给定类型封送到多个类型时需要此属性。例如,String 可能作为LPStr、LPWStr、LPTStr或BStr封送到非托管代码。默认情况下,字符串作为BStr封送到 COM 方法。可将MarshalAsAttribute属性应用于个别的字段或参数,以使该字符串作为LPStr而非BStr封送。有关如何使用此属性的完整详细信息,请参阅“数据封送处理规范”。

大多数情况下,该属性只是使用UnmanagedType枚举标识非托管数据的格式,如下面的示例所示。

[C#] 
void MyMethod([MarshalAs(LPStr)] String s);
某些UnmanagedType枚举需要附加信息。例如,当UnmanagedType为LPArray时需要附加信息。有关如何使用此属性的完整说明,请参阅“数据封送处理规范”。

 

 

[]C#C/C++类型对照表2010-04-07 11:04

http://www.soasp.net/FilePage/200804/20080404233928.htm

注意:c++的类型的头文件为:Wtypes.h

C++            C#
=====================================
WORD            ushort
DWORD            uint
UCHAR            int/byte   大部分情况都可以使用int代替,而如果需要严格对齐的话则应该用bytebyte 
UCHAR*            string/IntPtr
unsigned char*         [MarshalAs(UnmanagedType.LPArray)]byte[]/?(Intptr)
char*            string
LPCTSTR            string
LPTSTR            [MarshalAs(UnmanagedType.LPTStr)] string
long            int
ulong               uint
Handle            IntPtr
HWND            IntPtr
void*            IntPtr
int            int
int*            ref int
*int            IntPtr
unsigned int        uint
COLORREF                uint

API与C#的数据类型对应关系表

API数据类型

类型描述

C#类型

API数据类型

类型描述

C#类型

WORD

16位无符号整数

ushort

CHAR

字符

char

LONG

32位无符号整数

int

DWORDLONG

64位长整数

long

DWORD

32位无符号整数

uint

HDC

设备描述表句柄

int

HANDLE

句柄,32位整数

int

HGDIOBJ

GDI对象句柄

int

UINT

32位无符号整数

uint

HINSTANCE

实例句柄

int

BOOL

32位布尔型整数

bool

HWM

窗口句柄

int

LPSTR

指向字符的32位指针

string

HPARAM

32位消息参数

int

LPCSTR

指向常字符的32位指针

String

LPARAM

32位消息参数

int

BYTE

字节

byte

WPARAM

32位消息参数

int

BOOL=System.Int32
BOOLEAN=System.Int32
BYTE=System.UInt16
CHAR=System.Int16
COLORREF=System.UInt32
DWORD=System.UInt32
DWORD32=System.UInt32
DWORD64=System.UInt64
FLOAT=System.Float
HACCEL=System.IntPtr
HANDLE=System.IntPtr
HBITMAP=System.IntPtr
HBRUSH=System.IntPtr
HCONV=System.IntPtr
HCONVLIST=System.IntPtr
HCURSOR=System.IntPtr
HDC=System.IntPtr
HDDEDATA=System.IntPtr
HDESK=System.IntPtr
HDROP=System.IntPtr
HDWP=System.IntPtr
HENHMETAFILE=System.IntPtr
HFILE=System.IntPtr
HFONT=System.IntPtr
HGDIOBJ=System.IntPtr
HGLOBAL=System.IntPtr
HHOOK=System.IntPtr
HICON=System.IntPtr
HIMAGELIST=System.IntPtr
HIMC=System.IntPtr
HINSTANCE=System.IntPtr
HKEY=System.IntPtr
HLOCAL=System.IntPtr
HMENU=System.IntPtr
HMETAFILE=System.IntPtr
HMODULE=System.IntPtr
HMONITOR=System.IntPtr
HPALETTE=System.IntPtr
HPEN=System.IntPtr
HRGN=System.IntPtr
HRSRC=System.IntPtr
HSZ=System.IntPtr
HWINSTA=System.IntPtr
HWND=System.IntPtr
INT=System.Int32
INT32=System.Int32
INT64=System.Int64
LONG=System.Int32
LONG32=System.Int32
LONG64=System.Int64
LONGLONG=System.Int64
LPARAM=System.IntPtr
LPBOOL=System.Int16[]
LPBYTE=System.UInt16[]
LPCOLORREF=System.UInt32[]
LPCSTR=System.String
LPCTSTR=System.String
LPCVOID=System.UInt32
LPCWSTR=System.String
LPDWORD=System.UInt32[]
LPHANDLE=System.UInt32
LPINT=System.Int32[]
LPLONG=System.Int32[]
LPSTR=System.String
LPTSTR=System.String
LPVOID=System.UInt32
LPWORD=System.Int32[]
LPWSTR=System.String
LRESULT=System.IntPtr
PBOOL=System.Int16[]
PBOOLEAN=System.Int16[]
PBYTE=System.UInt16[]
PCHAR=System.Char[]
PCSTR=System.String
PCTSTR=System.String
PCWCH=System.UInt32
PCWSTR=System.UInt32
PDWORD=System.Int32[]
PFLOAT=System.Float[]
PHANDLE=System.UInt32
PHKEY=System.UInt32
PINT=System.Int32[]
PLCID=System.UInt32
PLONG=System.Int32[]
PLUID=System.UInt32
PSHORT=System.Int16[]
PSTR=System.String
PTBYTE=System.Char[]
PTCHAR=System.Char[]
PTSTR=System.String
PUCHAR=System.Char[]
PUINT=System.UInt32[]
PULONG=System.UInt32[]
PUSHORT=System.UInt16[]
PVOID=System.UInt32
PWCHAR=System.Char[]
PWORD=System.Int16[]
PWSTR=System.String
REGSAM=System.UInt32
SC_HANDLE=System.IntPtr
SC_LOCK=System.IntPtr
SHORT=System.Int16
SIZE_T=System.UInt32
SSIZE_=System.UInt32
TBYTE=System.Char
TCHAR=System.Char
UCHAR=System.Byte
UINT=System.UInt32
UINT32=System.UInt32
UINT64=System.UInt64
ULONG=System.UInt32
ULONG32=System.UInt32
ULONG64=System.UInt64
ULONGLONG=System.UInt64
USHORT=System.UInt16
WORD=System.UInt16
WPARAM=System.IntPtr

<---------补充----------->

Wtypes.h中的非托管类型    非托管C 语言类型    托管类名       说明 
HANDLE                         void*                   System.IntPtr 32 位 
BYTE                             unsigned char       System.Byte    8 位 
SHORT                          short                    System.Int16   16 位 
WORD                           unsigned short      System.UInt16 16 位 
INT                                int                       System.Int32   32 位 
UINT                              unsigned int         System.UInt32 32 位 
LONG                             long                    System.Int32   32 位 
BOOL                             long                    System.Int32   32 位 
DWORD                         unsigned long       System.UInt32 32 位 
ULONG                           unsigned long       System.UInt32 32 位 
CHAR                             char                    System.Char    用 ANSI 修饰。 
LPSTR                            char*                  System.String或System.StringBuilder用 ANSI 修饰。 
LPCSTR                          Const char*         System.String或System.StringBuilder用 ANSI 修饰。 
LPWSTR                         wchar_t*             System.String或System.StringBuilder用 Unicode 修饰。 
LPCWSTR                       Constwchar_t*     System.String或System.StringBuilder用 Unicode 修饰。 
FLOAT                            Float                    System.Single 32 位 
DOUBLE                         Double                 System.Double 64 位


0 0
原创粉丝点击