注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

共享圈

www.gxquan.com的同步博客,保存高质量文章之用

 
 
 

日志

 
 

C#调用C/C++ 动态链接库DLL  

2012-10-19 23:42:49|  分类: C/C++ WindowsSDK |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

(一)调用DLL中的非托管函数一般方法

首先,应该在C#语言源程序中声明外部方法,其基本形式是:

[DLLImport(“DLL文件”)]

修饰符 extern 返回变量类型 方法名称 (参数列表)

其中:

DLL文件:包含定义外部方法的库文件。

修饰符: 访问修饰符,除了abstract以外在声明方法时可以使用的修饰符。

返回变量类型:在DLL文件中你需调用方法的返回变量类型。

方法名称:在DLL文件中你需调用方法的名称。

参数列表:在DLL文件中你需调用方法的列表。

注意:需要在程序声明中使用System.Runtime.InteropServices命名空间。

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

DLL文件必须位于程序当前目录或系统定义的查询路径中(即:系统环境变量中Path所设置的路径)。

返回变量类型、方法名称、参数列表一定要与DLL文件中的定义相一致。

 

若要使用其它函数名,可以使用EntryPoint属性设置,如:

[DllImport("user32.dll", EntryPoint="MessageBoxA")]

static extern int MsgBox(int hWnd, string msg, string caption, int type);

其它可选的 DllImportAttribute 属性:

CharSet 指示用在入口点中的字符集,如:CharSet=CharSet.Ansi;

SetLastError 指示方法是否保留 Win32"上一错误",如:SetLastError=true;

ExactSpelling 指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配,如:ExactSpelling=false;

PreserveSig指示方法的签名应当被保留还是被转换, 如:PreserveSig=true;

CallingConvention指示入口点的调用约定,如:CallingConvention=CallingConvention.Winapi;


1. C#与 C/C++的常用等效类型

wtypes.h

Visual C++

Visual C++ with /clr

Common language runtime

HANDLE

void *

void *

IntPtr, UIntPtr

BYTE

unsigned char

unsigned char

Byte

SHORT

short

short

Int16

WORD

unsigned short

unsigned short

UInt16

INT

int

int

Int32

UINT

unsigned int

unsigned int

UInt32

LONG

long

long

Int32

BOOL

long

bool

Boolean

DWORD

unsigned long

unsigned long

UInt32

ULONG

unsigned long

unsigned long

UInt32

CHAR

char

char

Char

LPCSTR

char *

String ^ [in], StringBuilder ^ [in, out]

String ^ [in], StringBuilder ^ [in, out]

LPCSTR

const char *

String ^

String

LPWSTR

wchar_t *

String ^ [in], StringBuilder ^ [in, out]

String ^ [in], StringBuilder ^ [in, out]

LPCWSTR

const wchar_t *

String ^

String

FLOAT

float

float

Single

DOUBLE

double

double

Double

2。 创建C#与C/C++互操作DLL的步骤

1) 创建C/C++动态链接库,导出接口函数;

2) 在C#中创建接口的声明,导入接口函数;

3) 调用函数。

2. 在C#中创建DLL接口的声明

C#没有全局函数,必须使用静态函数实现全局函数。

1)  DllImport类似C++中的__declspec(dllimport),第一个参数为必选参数,为DLL的路径,一般以相对路径即可,只需要将DLL文件放到工作目录中即可

2) EntryPoint表示对应的函数名称,这个与C++ DLL工程中.def文件中导出的函数名同

使用C#调用C++时不支持C++的函数名重载(至少还没有找到办法),如果参数不同必须使用不同的函数名用以区分,但在C#中可以使用相同的函数名

3) C#中的声明的函数名不一定与实际的函数名一样,比如

[csharp] view plaincopy
  1. public static extern int PassString(string msg);  

中的PassString可以使用任何名称,与C++中的对应关系只需要DllImport中的EntryPoint参数保持一致。

一般地只需要给出DLL文件名、EntryPoint两个参数就可以了。

[csharp] view plaincopy
  1.   
[csharp] view plaincopy
  1. using System;  
  2. using System.Runtime.InteropServices;  
  3. using Noock.TTest;  
[csharp] view plaincopy
  1. public static class CFuncs  
  2.     {  
  3.         [DllImport("dlldemo.dll", EntryPoint = "PassString", CharSet = CharSet.Ansi,  
  4.                     CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]  
  5.         public static extern int PassString(string msg);  
  6.   
  7.         [DllImport("dlldemo.dll", EntryPoint = "Power", CharSet = CharSet.Ansi,  
  8.                     CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]  
  9.         public static extern double Power(double x, int y);  
  10.   
  11.         public struct Location  
  评论这张
 
阅读(135)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017