热点推荐

查看: 3673|回复: 8
收起左侧

[资料] C#调用C/C++动态链接库(.dll)详解

[复制链接]
  • TA的每日心情
    慵懒
    昨天 10:41
  • 签到天数: 425 天

    连续签到: 70 天

    [LV.9]以坛为家II

    358

    主题

    1261

    帖子

    9509

    积分

    Rank: 9

    积分
    9509

    突出贡献优秀版主荣誉管理论坛元老优质会员最佳新人

    发表于 2017-1-6 10:54:23 | 显示全部楼层 |阅读模式

    51Halcon诚邀您的加入,专注于机器视觉开发与应用技术,我们一直都在努力!

    您需要 登录 才可以下载或查看,没有帐号?会员注册

    x
    第一篇编译C的动态连接库

    在实际工作中,我们经常会将C语言中的.lib和.h文件(静态库)编译成动态连接库.dll文件(这里只提供这两种文件,没有完整的工程),以提供给其他语言平台调用。
    1,必须有.lib文件,只有.h文件是无法编译动态连接库的。
    2,我使用的是VS2008,这里打开VS,新建项目—〉win32控制台应用程序,输入项目名称,点击确定,图示如fig.1所示。
    1022880065384070083.jpg

    3,点击下一步,依次如图fig.2-3所示,最后点击完成,就会生成一个带有.cpp的文件。
    2548192964179112583.jpg
    2723270399693140519.jpg

    4,打开项目—属性—配置属性—链接器—输入,如下图fig.4所示,在附加依赖项中加入你要添加的.lib文件,如果有一些系统.lib库没有添加或出现错误,可以在忽略特定库中添加该库。
    注意:如果编译的dll文件调用中出现“xx.dll中找不到函数xx的入口点”,很有可能是一个xx.def文件没有添加,该文件的内容是EXPORTS  函数名@+序号,将xx.def这个名字填写到下图界面的“模块定义文件”,格式为“./xx.def”。如果这个文件中没有你要调用的API 函数,那么你在C#中是调用不到这个函数的,同时这个文件你可以通过记事本自己编辑,注意!!!

    2579999636547418717.jpg

    5,在.cpp文件中添加.h文件的引用,不需要把所有的.h文件都引用进去,只需要.lib文件入口相关的.h文件。
    6,最后把.lib和.h文件拷贝到工程debug目录里,生成解决方案就Ok了,你会发现.dll在debug目录中出现。
    7,最后附上xx.def的格式说明
    EXPORTS
           Fuc1       @    1
           Fuc2       @    2
           Fuc3       @    3
        。。。。。。。省略了呵呵


    第二篇C#调用C/C++的动态连接库

    1,清楚C++与C#类型对应关系,即调用关系:
    2717077950205500173.jpg

    除此之外,
    c++:HANDLE(void *) ---- c#:System.IntPtr
    c++:WORD(unsigned short) ---- c#:System.UInt16
    c++:DWORD(unsigned long) ---- c#:System.UInt32
    c++:结构体 ---- c#:public struct 结构体{};
    c++:结构体 &变量名 ---- c#:ref 结构体 变量名
    c++:结构体 **变量名 ---- c#:out
    c++:GUID ---- c#:Guid
    c++:UINT8 * ---- c#:ref byte
    c++:char*/void*(指向一个字符串) ---- c#:string
    对于结构体中的指针数组,对应于C#中的IntPtr[]类型,如:   
    int * a[] -------------- IntPtr[]a
    2,清楚在C#中调用C/C++.dll文件的一般格式
    using System.Runtime.InteropServices; //必须引用的命名空间
    [DllImport("user32.dll")]
    public static extern ReturnType FunctionName(type arg1,type arg2,...);
    //必须定义为类的静态外部的方法
    3,[DllImport(参数)]设定
    ①“xx.dll” :dll文件名字
    ②CharSet :控制调用函数的名称版本及指示如何向方法封送 String 参数。如果 CharSet 字段设置为 Unicode,则所有字符串参数在传递到非托管实现之前都转换成 Unicode 字符。这还导致向 DLL EntryPoint 的名称中追加字母“W”。如果此字段设置为 Ansi,则字符串将转换成 ANSI 字符串,同时向 DLL EntryPoint 的名称中追加字母“A”。
    EntryPoint 指示要调用的 DLL 入口点的名称或序号。如果你想使用自己定义的函数名字fucXX,则:”EntryPoint=fucXX”。
    ③ExactSpelling:指示是否应修改非托管 DLL 中的入口点的名称,以与 CharSet 字段中指定的 CharSet 值相对应。如果为 true,则当 DllImportAttribute.CharSet 字段设置为 CharSet 的 Ansi 值时,向方法名称中追加字母 A,当 DllImportAttribute.CharSet 字段设置为 CharSet 的 Unicode 值时,向方法的名称中追加字母 W。此字段的默认值是 false。
    ④PreserveSig:指示托管方法签名不应转换成返回 HRESULT、并且可能有一个对应于返回值的附加 [out, retval] 参数的非托管签名。
    ⑤SetLastError:指示被调用方在从属性化方法返回之前将调用 Win32 API SetLastError。 true 指示调用方将调用 SetLastError,默认为 false。
    4,具体实例
    C中API函数:
    1. Unsigned long int Fuc (int a,void* b);
    复制代码

    C#中定义:
    1. [DllImport("testall.dll", ExactSpelling = false)]
    2. public extern static UInt32 Fuc(int a, IntPtr b);//
    3. C中结构体:
    4. #define M 5
    5. typedef struct __BITMAP{
    6. DWord pPixelArrayFormat;
    7. Long lWidth;
    8. Long lHeight;
    9. Long lBuffer [MPAF_MAX_PLANES];
    10. Byte* pPointer[MPAF_MAX_PLANES];
    11. }BITMAP
    复制代码

    C#定义:
    1. [StructLayout(LayoutKind.Sequential)] //此句在C#中重新定义结构体时一定要加上
    2.         public struct BITMAP
    3.         {
    4.             [MarshalAs(UnmanagedType.U4)]
    5.             public UInt32 pPixelArrayFormat;
    6.             [MarshalAs(UnmanagedType.I4)]
    7.             public Int32 lWidth;
    8.             [MarshalAs(UnmanagedType.I4)]
    9.             public Int32 lHeight;
    10.             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
    11.             public Int32[] lBuffer;
    12.             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
    13.             public IntPtr[] pPointer;   //对于结构体中的指针数组,一般采用IntPtr数组
    14.         }
    复制代码

    对于上面的这个结构体,如果在C/C++中出现了结构体指针,那么我们应该在C#中使用IntPtr类型变量,然后使用如下方法将指针指向结构体。
    定义结构体对象S,则在C#中获取结构体指针的方法如下:
    IntPtr intptr = Marshal.AllocHGlobal(Marshal.SizeOf(S));
    Marshal.StructureToPtr(S, intptr, false); //将指针intptr指向结构体
    操作之后一定要释放内存——
    Marshal.FreeHGlobal(intptr);//释放分配的非托管内存。
    反之也可以由指向结构体的指针变量获取结构体。Marshal.PtrToStructure();
    无效附件更新 权限提升操作 删帖申请 举报以及其他需要帮助请加入QQ群:214663141 广告位招商 有意者联系

    该用户从未签到

    0

    主题

    36

    帖子

    531

    积分

    Rank: 4Rank: 4

    积分
    531
    发表于 2017-2-3 11:25:46 | 显示全部楼层
    路过 分享 希望以后用得上!

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

    如何回报帮助你解决问题的坛友,可以以【悬赏】的方式提问,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    慵懒
    2018-4-19 16:23
  • 签到天数: 26 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    0

    主题

    54

    帖子

    310

    积分

    Rank: 2Rank: 2

    积分
    310
    发表于 2017-10-23 20:57:58 | 显示全部楼层
    路过 分享 希望以后用得上!

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

    如何回报帮助你解决问题的坛友,可以以【悬赏】的方式提问,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    郁闷
    2018-3-7 14:29
  • 签到天数: 18 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    3

    主题

    73

    帖子

    379

    积分

    Rank: 2Rank: 2

    积分
    379
    发表于 2017-11-4 11:24:31 | 显示全部楼层

    新手过来学习学习

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

    如何回报帮助你解决问题的坛友,可以以【悬赏】的方式提问,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    开心
    2018-10-19 08:56
  • 签到天数: 27 天

    连续签到: 2 天

    [LV.4]偶尔看看III

    0

    主题

    28

    帖子

    541

    积分

    Rank: 3

    积分
    541

    活跃会员

    发表于 2018-2-1 15:33:48 | 显示全部楼层

    好东西,分享一下

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

    如何回报帮助你解决问题的坛友,可以以【悬赏】的方式提问,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    开心
    2018-10-19 08:56
  • 签到天数: 27 天

    连续签到: 2 天

    [LV.4]偶尔看看III

    0

    主题

    28

    帖子

    541

    积分

    Rank: 3

    积分
    541

    活跃会员

    发表于 2018-2-1 15:35:07 | 显示全部楼层

    好东西,分享一下

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

    如何回报帮助你解决问题的坛友,可以以【悬赏】的方式提问,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    开心
    2018-10-19 08:56
  • 签到天数: 27 天

    连续签到: 2 天

    [LV.4]偶尔看看III

    0

    主题

    28

    帖子

    541

    积分

    Rank: 3

    积分
    541

    活跃会员

    发表于 2018-2-1 15:35:38 | 显示全部楼层

    好东西,分享一下

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

    如何回报帮助你解决问题的坛友,可以以【悬赏】的方式提问,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    擦汗
    2018-9-3 08:55
  • 签到天数: 10 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    0

    主题

    26

    帖子

    2570

    积分

    Rank: 5Rank: 5Rank: 5

    积分
    2570

    优质会员

    发表于 2018-8-24 14:44:50 | 显示全部楼层
    路过,记录学习.......

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

    如何回报帮助你解决问题的坛友,可以以【悬赏】的方式提问,伸手党遭人唾弃,做一个热心并受欢迎的人!

    您需要登录后才可以回帖 会员登录 | 会员注册

    本版积分规则

    经营性网站备案信息 经营性网站
    备案信息

    中国互联网举报中心 中国互联网
    举报中心

    中国文明网传播文明 中国文明网
    传播文明

    诚信网站

    深圳市市场监督管理局企业主体身份公示 工商网监
    电子标识

    快速回复 返回顶部 返回列表