图片 3

c#(winform)环境下使用动态链接库dll的详解

  •   引用库使用 #using “xxx.dll” 这里需要制定dll的相对路径
  • #pragma managed;  // 告诉编译器,将使用托管代码

  • using namespace CsDll002;  // 引入名字空间

&
ref 取地址

 

3,托管dll和非托管dll如何使用?

不能解决的问题:

DLL(Dynamic Link
Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件。

5.使用类库

//short
(const char *ipaddr, unsigned short port, long timeout, unsigned short
*FlibHndl)

 

example:

此文章演示了建立c#的dll;

PreserveSig
       托管方法签
名是否转换成返回
HRESULT,默认值为 true(不应转换签名)。并且返回值有一个附加的
[out, retval] 参数的非托管签名。  

图片 1

short int16 短整型

 

C
C# 备注

2.修改输出路径输出为 ../bin/debug; ../bin/release 方便c++可以定位找到

//分配的库处理和连接到数控指定的IP地址或主机名。

图片 2

(整理,源文章来源于网络)

c++建立工程,引入dll;

ref
要求参数在传递给函数前要初始化,out则不需要,常见于平台调用中。out和ref传递的都是引用而不是值,out侧重于输出使用之前不需赋值而ref在使用之前需要赋值,另外这两个关键字可以变相实现使一个方法输出多个值。ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以你必须初始化一次。这个就是两个的区别,或者说就像有的网友说的,ref是有进有出,out是只出不进。说明是引用的传递。

 

int int32 整型

1-建立c#的dll,过程略;

[DllImport(“Fwlib64.dll”,
EntryPoint = “cnc_allclibhndl3”,
CallingConvention=CallingConvention.Cdecl)]

4.新添加的C++工程,引用DLL,同时引入名字空间;

托管dll在VS环境下使用相对容易,可以在项目名上右击选择添加应用的方式导入dll,本文这里不作详解。非托管dll的使用步骤及如下:

与C#区别,如果c# 写的函数是 int  add(int a, int b, ref int resut) 
调用时需要 add(1, 2, ref result);这里C++没有这个语法要求。

c#中修饰符ref、out的作用及功能

 尖号表示托管;这里演示了返回值使用引用,和C++调用引用一样,不需要指定特殊字符;

2,使用DllImport导入非托管dll。

图片 3

//命名空间

3.在解决方案添加C++工程,过程略

1,什么是dll文件?

 

long int64 长整型

指定dll的路径,在代码里面直接写 #using “xxx.dll” 必须要在使用路径
#using “../bin/debug/xxx.dll”

DllImport的可选属性参数说明:
EntryPoint
        指定要调用的 DLL 入口点。 
SetLastError
      判断在执行该方法时是否出错(使用 Marshal.GetLastWin32Error API
函数来确定)。C#中默认值为
false。
CharSet
           控制名称及函数中字符串参数的编码方式。默认值为
CharSet.Ansi。
ExactSpelling
     是否修改入口点以对应不同的字符编码方式。
CallingConvention
 指定用于传递方法参数的调用约定。默认值为
WinAPI。该值对应于基于32位Intel平台的 __stdcall。
BestFitMapping
    是否启用最佳映射功能,默认为 true。最佳映射功能提供在没有匹配项时,自动提供匹配的字符。无法映射的字符通常转换为默认的“?”。

c++调用c#写的DLL;

private
static extern Int16 cnc_allclibhndl3(ref String ip, UInt16 port, Int64
timeout, ref UInt16 flibHndl);

 

using
System.Runtime.InteropServices;

DllImport会按照以下3种顺序查找dll文件:
1)、exe所在目录;
2)、System32目录(系统目录);

//导入非托管dll

1,需要检查使用的dll的目标平台(Any
Cpu,x86,x64),在项目属性生成选项卡中选择与dll相对应的目标平台。因为托管dll是在.net的环境下生成的,转换为机器语言后能够自动识别目标平台即有框架支持解释,而非托管不能够自己识别需要人为的设置。

4)、必须引入System.Runtime.InteropServices命名空间。

3)、环境变量目录。(即需要将dll及依赖文件放到3个目录中的任何一个目录中)。

托管DLL就是能够在公共语言运行库(Common
Language
Runtime,简称CLR)中能够直接引用的,并且扩展为“DLL”的文件。具体所指就是封装各种命名空间所在的DLL文件,如System.dll等。非托管DLL就是平常所的动态链接库等,其中就包括了封装所有Windows
API函数的DLL文件。各种非托管DLL中的函数在公共语言运行库中不能直接被调用,而需要经过.Net框架提供的“平台调用”服务后才可以。(简而言之就是.net环境下生成的动态链接库为托管dll,相反则为非托管dll)

ThrowOnUnmappableChar
    控制对转换为 ANSI ‘?’ 字符的不可映射的 Unicode
字符引发异常。

DllImport的导入规则:
1)、方法名与Win
API完全一样。如果在C#中调用时显示完全不同的方法名称,则需要引入EntryPoint属性,使用别名显示。
2)、函数除需要DllImport类修饰符外,还需要声明public
static extern类型。
3)、函数返回值和参数必须和调用的API的完全一样。

* ref 指针

4,c#与c++、c动态链接库的参数如何对应?

2,托管dll和非托管dll区别是什么?