C#程序实现动态调用非托管的DLL文件
来源:互联网 发布:阿里云9.9学生机怎么用 编辑:程序博客网 时间:2024/05/18 03:16
C#程序实现动态调用非托管的DLL文件
最近的一个项目需要用C#调用C++的Dll,由于C++的Dll是非托管的,所以调用时需要一些技巧。下面分享给新手。
一.Dll文件
动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文件,Windows就是将一些主要的系统功能以DLL模块的形式实现。
动态链接库是不能直接执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成一定操作的函数(方法。注:C#中一般称为“方法”),但这些函数不是执行程序本身的一部分,而是根据进程的需要按需载入,此时才能发挥作用。
DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程所使用,而调用进程的句柄也可以被该DLL所使用。在内存中,一个DLL只有一个实例,且它的编制与具体的编程语言和编译器都没有关系,所以可以通过DLL来实现混合语言编程。DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。
二、 DLL的调用
每种编程语言调用DLL的方法都不尽相同,在此只对用C#调用DLL的方法进行介绍。首先,您需要了解什么是托管,什么是非托管。一般可以认为:非托管代码主要是基于win 32平台开发的DLL,activeX的组件,托管代码是基于.net平台开发的。如果您想深入了解托管与非托管的关系与区别,及它们的运行机制,请您自行查找资料,本文件在此不作讨论。
(一) 调用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;
基本的方法就是这样,大家可以尝试一下。
public static extern int Init_com(char* set);
我用
[DllImport("ICcard_dll.dll",CharSet=CharSet.Ansi)]
public static extern int Init_com(string set);
string StrConnect="1,9600,N,8,4";
iret = Init_com(StrConnect);
这样用
[DllImport("ICcard_dll.dll",CharSet=CharSet.Ansi)]
public static extern int Init_com(ref char set);
string StrConnect="1,9600,N,8,4";
要怎么把string数据在c#中表示成char*呢?
这样会说参数出错。
我该怎么用呢,高手救命啊!
- michaelnami
- (michaelnami)
- 等 级:
- dezhengwei
- (dezhengwei)
- 等 级:
我这样用了的,还是不对啊,报参数出错了
- hdt
- (倦怠)
- 等 级:
intptr 或者 stringbuilder
- wanghui0380
- (放歌)
- 等 级:
不out的,可以直接用string 或char[]
out的使用StringBuilder或intptr
- yue_shanglin
- (花痴)
- 等 级:
[DllImport("ICcard_dll.dll",CharSet=CharSet.Ansi)]
public static extern int Init_com(ref byte* set);
例如:
string strbuffer = "test";//测试字符串
int result = Init_com(ref Syste.Encoding.Ascii.GetBytes(strbuffer));
这样调用函数就可以了
- yue_shanglin
- (花痴)
- 等 级:
就该这样:
[DllImport("ICcard_dll.dll",CharSet=CharSet.Ansi)]
public static extern int Init_com(ref char* set);
int result = Init_com(ref str.ToCharArray());就OK
如果dll中的原型是Init_com(unsigned char* )的话,才是我上面说的那种
C++和C#数据类型的对应关系是char->char ;unsigned char ->byte
- bamboo2000
- (龙的传人)
- 等 级:
如果不是 out 就是 string
如果 out 就用 System.Text.StringBuilder
- yue_shanglin
- (花痴)
- 等 级:
这样子来构建C#函数也是可以的,这里的数据类型不必和C++函数保持一致的
- C# code
- [DllImport("ICcard_dll.dll",CharSet=CharSet.Ansi)] public static extern int Init_com(ref string set);
- bamboo2000
- (龙的传人)
- 等 级:
[DllImport("Del_dll.dll")]
public static extern int GetStrLen();
[DllImport("Del_dll.dll")]
public static extern bool UCase(System.Text.StringBuilder str);
其中Delphi源码为:
function GetStrLen(str:Pchar): integer; stdcall;
begin
Result := Length(str);
end;
function UCase(str:PChar): boolean; stdcall;
var
s: string;
begin
s:=Uppercase(strPas(str));
CopyMemory(str,pchar(s),Length(s));
result:=true;
end;
调用:
int len = GetStrLen("abcdefg");
StringBuilder str2 = new StringBuilder("abcdefg hijklmn OPQRST uvwxyz");
if (UCase(str2)) {
...
}
- mjp1234airen4385
- (骏马)
- 等 级:
- dezhengwei
- (dezhengwei)
- 等 级:
- holyrong
- 等 级:
怎么解决的?
- C#程序实现动态调用非托管的DLL文件
- C#程序实现动态调用非托管的DLL文件
- C#程序实现动态调用非托管的DLL文件
- C#程序实现动态调用非托管的DLL文件
- C#程序调用非托管C++ DLL文件的方法
- C#程序调用非托管C++ DLL文件的方法
- C#动态调用非托管DLL(一)
- C#动态调用非托管DLL(二)
- C#动态调用非托管DLL
- 【好文章要分享】C#程序调用非托管C++ DLL文件的方法
- C#调用非托管C++生成的DLL文件
- C#调用非托管DLL的APIs
- C#调用非托管DLL的APIs
- 非托管Dll动态调用
- 在非托管的 VC++2005 中调用托管的 C# DLL 文件
- C#调用非托管DLL
- C#调用非托管DLL
- C#调用非托管Dll
- silverlight 乐动魔方 实战三
- 写excel(二)
- mybatis generator eclipse插件的安装
- Dom笔记5:document对象的属性
- mybatis 学习 二、SQL语句映射文件(2)增删改查、参数、缓存
- C#程序实现动态调用非托管的DLL文件
- CString GetBuffer 获得 TCHAR指针
- 让DIV在弹出位置在屏幕中间
- Unicode汉字编码表
- sdsd
- XXX could not be redeployed because it could not be completely removed in the undeployment phase
- 职场人际关系法则
- Java程序设计与项目实战(全程实录)全新上市
- 实现Action(一)