呵呵..,又到了我有想写点东西的时候了.最近在论坛老是看见有朋友问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 位 |