C# 调用C++dll(以基恩士LKG5000为例)
最近有一个基恩士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(¶mEther);((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为例)相关推荐
- C# 调用C++ dll 返回char*调用方式(StringBuilder乱码)
// CDLLDemo.cpp : 定义 DLL 应用程序的导出函数. // #include "stdafx.h" #include "string.h" # ...
- C#调用C++DLL类的方法
C++的优势在于高效灵活,C#的优势在于简单易用,两者结合起来对项目开发来说是件好事,而且C++不容易反编译,也保障了代码的安全性,如果一些核心算法使用C#编写,那么保密就是一个问题. C++ ...
- c怎么调用matlab dll,matlab和c++调用DLL方法(最新整理)
<matlab和c++调用DLL方法(最新整理)>由会员分享,可在线阅读,更多相关<matlab和c++调用DLL方法(最新整理)(6页珍藏版)>请在人人文库网上搜索. 1.M ...
- Python:使用ctypes库调用外部DLL 数据类型对应
Python:使用ctypes库调用外部DLL(转) 前言
- C#调用C++dll
1.添加命名空间 using System.Runtime.InteropServices; 2.dll的添加和函数的声明(注意一定要放在函数(方法)的外面) [DllImport("Use ...
- 在一个解决方案中用C#测试调用C++ DLL
VS2015,在解决方案中新建一个C++ DLL项目,一个C# Winform项目: dllmain.cpp; #include "stdafx.h"BOOL APIENTRY D ...
- [.NET开发] C#编程调用Cards.dll实现图形化发牌功能示例
本文实例讲述了C#编程调用Cards.dll实现图形化发牌功能.分享给大家供大家参考,具体如下: using System; using System.Collections.Generic; usi ...
- 非常好的dllimport 文章--在 C# 中通过 P/Invoke 调用Win32 DLL
http://msdn.microsoft.com/zh-cn/library/aa686045.aspx 在 C# 中通过 P/Invoke 调用Win32 DLL 发布日期 : 1/13/2005 ...
- 如何在MFC客户端调用COM DLL
也许有人会认为这是一个非常小儿科的问题.不过,我还是颇花费了一点时间和精力才搞清楚的.OK, 下面简单谈一下如何去做. 可以有很多方法生成一个COM DLL.比如,VB, VC++, DELPHI等等 ...
最新文章
- 聚美优品 html 资源,跨界整合行业资源 聚美优品向阳而生
- HTC与酷派 不是冤家不聚头
- POJ 2800 垂直直方图 解题报告
- 未来期间的过帐运行已申请(检查条目)
- iqn怎么查 linux_程序员必备:46个Linux面试常见问题!收藏!
- Mybatis传入多参问题
- SAP Spartacus新建org unit之后,排序不正确的问题分析
- 【C++深度剖析教程32】new/malloc区别 delete/free区别
- 网页开发部署-开发工具MyEclips+Tomcat+mysql
- 【万字总结,花几分钟让你进一步了解指针】(学习笔记11--指针中)
- Java案例:功夫熊猫
- QTreeView使用系列教程目录
- 英国资深律师称加密货币和智能合约必然将成为社会主流
- sql语句连接查询.
- CMStudio中出现‘$错误‘ is not a vaild integer value如何解决
- 一个数据分析报告的框架,主要包含哪几项?
- 坦克大战第一个不爆炸
- 天威诚信:数字认证体系助推车联网积极稳妥发展
- 泛微oa流程表单之请假单(判断请假结束时间不能小于等于请假开始时间)
- panda开始python的数据科学
热门文章
- idea搜不到子目录下的配置怎么解决
- 互联网应用开发实践:需求分析与数据库设计
- 信号完整性(SI)电源完整性(PI)学习笔记(三十四)100条估计信号完整性效应的经验法则
- 第8天-信息收集——站点搭建,WAF等
- python去除字符串中的空格、特殊字符、指定字符
- 手机APP开发:学JAVA转安卓APP开发是不是很容易?
- camera中文版软件 ip_911 S5使用教程动态IP代理配置VMlogin中文版反指纹浏览器Multilogin浏览器教程...
- 罗克韦尔自动化帮助简化工业生产力分析
- c语言判断非法字符题目,C语言考试题库之判断题-c语言考试判断题
- 好久没在线了,恩进修(偷懒)中,hahaha~整理一下