最近有一个基恩士LKG5000测距仪要用,LKG5000可以用RS232和以太网通信,无奈电器用了网线接口,因此只能用以太网通信了。

基恩士提供的以太网通信例程是基于C++的,因此需要用到C#调用C++ DLL的技术。

C#调用C++函数需要按如下格式进行声明:

     [DllImport("LKIF2.dll")]public extern static RC LKIF2_CloseDevice();

其中,在调用基恩士C++函数时我碰到了以下几种情况:

1,传入参数和返回值均为基本数据类型,这类函数按照上面的格式直接写,写完调用就可以了,非常简单

     [DllImport("LKIF2.dll")]public extern static bool LKIF_ClearFigureData();

2,传入参数和返回值中存在枚举类型,如这里的RC就是基恩士自定义的枚举类型,这时只需要在C#中按照C#的格式将这个枚举类写一遍就可以了

     [DllImport("LKIF2.dll")]public extern static RC LKIF2_CloseDevice();
     public enum RC{RC_OK = 0x0000,             // The operation is completed successfully.///// Communication error from controller notification//RC_NAK_COMMAND = 0x1001,    // Command errorRC_NAK_COMMAND_LENGTH,      // Command length errorRC_NAK_TIMEOUT,             // TimeoutRC_NAK_CHECKSUM,            // Check sum errorRC_NAK_INVALID_STATE,       // Status errorRC_NAK_OTHER,               // Other errorRC_NAK_PARAMETER,           // Parameter errorRC_NAK_OUT_STAGE,           // OUT calculation count limitation errorRC_NAK_OUT_HEAD_NUM,        // No. of used head/OUT over errorRC_NAK_OUT_INVALID_CALC,    // OUT which cannot be used for calculation was specified for calculation.RC_NAK_OUT_VOID,            // OUT which specified for calculation is not found.RC_NAK_INVALID_CYCLE,       // Unavailable sampling cycleRC_NAK_CTRL_ERROR,          // Main unit errorRC_NAK_SRAM_ERROR,          // Setting value error///// Communication DLL error notification//RC_ERR_OPEN_DEVICE = 0x2000,// Opening the device failed.RC_ERR_NO_DEVICE,           // The device is not open.RC_ERR_SEND,                // Command sending errorRC_ERR_RECEIVE,             // Response receiving errorRC_ERR_TIMEOUT,             // TimeoutRC_ERR_NODATA,              // No dataRC_ERR_NOMEMORY,            // No free memoryRC_ERR_DISCONNECT,          // Cable disconnection suspectedRC_ERR_UNKNOWN,             // Undefined error}

3,传入参数中带有结构体的,碰到这种实际上我感觉挺麻烦,因为结构体里面一般还会有结构体,并且还有各种关键字如union等。这里以连接函数为例:

EXP RC WINAPI LKIF2_OpenDeviceETHER(LKIF_OPENPARAM_ETHERNET * OpenParam);

这里出现了一个结构体

typedef struct {IN_ADDR              IPAddress;
} LKIF_OPENPARAM_ETHERNET;

结构体里面还有一个结构体

//
// IPv4 Internet address
// This is an 'on-wire' format structure.
//
typedef struct in_addr {union {struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;struct { USHORT s_w1,s_w2; } S_un_w;ULONG S_addr;} S_un;
#define s_addr  S_un.S_addr /* can be used for most tcp & ip code */
#define s_host  S_un.S_un_b.s_b2    // host on imp
#define s_net   S_un.S_un_b.s_b1    // network
#define s_imp   S_un.S_un_w.s_w2    // imp
#define s_impno S_un.S_un_b.s_b4    // imp #
#define s_lh    S_un.S_un_b.s_b3    // logical host
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;

可以看到in_addr结构体里面还使用了关键字union,意思是union里面的变量共用了一个地址(重点——),看到这里实际上我也不知道该怎么写了,这么复杂,下面还有一堆define关键字。

看回基恩士给的例程,噢,发现他虽然传入了LKIF_OPENPARAM_ETHERNET,但他只对S_addr进行了赋值,而S_un_b、S_un_w和S_addr又是公用一段地址的,那么我是否只需要在C#的结构体里声明一个ULONG 类型的变量就可以了呢?

 _sprintf_p(strIp,20,"%d.%d.%d.%d\0",_ttoi(strAddr[0]),_ttoi(strAddr[1]),_ttoi(strAddr[2]),_ttoi(strAddr[3]));LKIF_OPENPARAM_ETHERNET paramEther;paramEther.IPAddress.S_un.S_addr = inet_addr(strIp);if(paramEther.IPAddress.S_un.S_addr == INADDR_NONE){SHOW_ERROR_MSG;return;}RC rc = LKIF2_OpenDeviceETHER(&paramEther);((CLkIF2TestVCDlg*)GetParent())->DisplayCommandResult(_T("LKIF2_OpenDeviceETHER"),rc);

再进一步,既然只有一个变量,那么我是否可以直接将传入的参数更改为long,即如下面所示,因为只写一个long和写一堆结构体和union他们的地址是一样的

     [DllImport("LKIF2.dll")]public extern static RC LKIF2_OpenDeviceETHER(ref long IPAddress);

结果表明,这样写确实是可以的。虽然我没有研究过C#调用C++库的具体机制,但我猜想他是按照内存地址来读取和写入变量的,只要地址对的上,那最终结果就没有问题。

C# 调用C++dll(以基恩士LKG5000为例)相关推荐

  1. C# 调用C++ dll 返回char*调用方式(StringBuilder乱码)

    // CDLLDemo.cpp : 定义 DLL 应用程序的导出函数. // #include "stdafx.h" #include "string.h" # ...

  2. C#调用C++DLL类的方法

    C++的优势在于高效灵活,C#的优势在于简单易用,两者结合起来对项目开发来说是件好事,而且C++不容易反编译,也保障了代码的安全性,如果一些核心算法使用C#编写,那么保密就是一个问题.     C++ ...

  3. c怎么调用matlab dll,matlab和c++调用DLL方法(最新整理)

    <matlab和c++调用DLL方法(最新整理)>由会员分享,可在线阅读,更多相关<matlab和c++调用DLL方法(最新整理)(6页珍藏版)>请在人人文库网上搜索. 1.M ...

  4. Python:使用ctypes库调用外部DLL 数据类型对应

    Python:使用ctypes库调用外部DLL(转) 前言

  5. C#调用C++dll

    1.添加命名空间 using System.Runtime.InteropServices; 2.dll的添加和函数的声明(注意一定要放在函数(方法)的外面) [DllImport("Use ...

  6. 在一个解决方案中用C#测试调用C++ DLL

    VS2015,在解决方案中新建一个C++ DLL项目,一个C# Winform项目: dllmain.cpp; #include "stdafx.h"BOOL APIENTRY D ...

  7. [.NET开发] C#编程调用Cards.dll实现图形化发牌功能示例

    本文实例讲述了C#编程调用Cards.dll实现图形化发牌功能.分享给大家供大家参考,具体如下: using System; using System.Collections.Generic; usi ...

  8. 非常好的dllimport 文章--在 C# 中通过 P/Invoke 调用Win32 DLL

    http://msdn.microsoft.com/zh-cn/library/aa686045.aspx 在 C# 中通过 P/Invoke 调用Win32 DLL 发布日期 : 1/13/2005 ...

  9. 如何在MFC客户端调用COM DLL

    也许有人会认为这是一个非常小儿科的问题.不过,我还是颇花费了一点时间和精力才搞清楚的.OK, 下面简单谈一下如何去做. 可以有很多方法生成一个COM DLL.比如,VB, VC++, DELPHI等等 ...

最新文章

  1. 聚美优品 html 资源,跨界整合行业资源 聚美优品向阳而生
  2. HTC与酷派 不是冤家不聚头
  3. POJ 2800 垂直直方图 解题报告
  4. 未来期间的过帐运行已申请(检查条目)
  5. iqn怎么查 linux_程序员必备:46个Linux面试常见问题!收藏!
  6. Mybatis传入多参问题
  7. SAP Spartacus新建org unit之后,排序不正确的问题分析
  8. 【C++深度剖析教程32】new/malloc区别 delete/free区别
  9. 网页开发部署-开发工具MyEclips+Tomcat+mysql
  10. 【万字总结,花几分钟让你进一步了解指针】(学习笔记11--指针中)
  11. Java案例:功夫熊猫
  12. QTreeView使用系列教程目录
  13. 英国资深律师称加密货币和智能合约必然将成为社会主流
  14. sql语句连接查询.
  15. CMStudio中出现‘$错误‘ is not a vaild integer value如何解决
  16. 一个数据分析报告的框架,主要包含哪几项?
  17. 坦克大战第一个不爆炸
  18. 天威诚信:数字认证体系助推车联网积极稳妥发展
  19. 泛微oa流程表单之请假单(判断请假结束时间不能小于等于请假开始时间)
  20. panda开始python的数据科学

热门文章

  1. idea搜不到子目录下的配置怎么解决
  2. 互联网应用开发实践:需求分析与数据库设计
  3. 信号完整性(SI)电源完整性(PI)学习笔记(三十四)100条估计信号完整性效应的经验法则
  4. 第8天-信息收集——站点搭建,WAF等
  5. python去除字符串中的空格、特殊字符、指定字符
  6. 手机APP开发:学JAVA转安卓APP开发是不是很容易?
  7. camera中文版软件 ip_911 S5使用教程动态IP代理配置VMlogin中文版反指纹浏览器Multilogin浏览器教程...
  8. 罗克韦尔自动化帮助简化工业生产力分析
  9. c语言判断非法字符题目,C语言考试题库之判断题-c语言考试判断题
  10. 好久没在线了,恩进修(偷懒)中,hahaha~整理一下