C#中使用DLL文件
首先,我们需要在C++程序中导出DLL文件。我使用的是Visual Studio开发,把项目"属性"中的“配置类型”改为"动态库dll",然后添加如下导出代码:
extern "C" __declspec(dllexport) void AS3911FindTag(Tag tags[], int &tagNum, int slot);//find tags
extern "C" __declspec(dllexport) bool GetTagInformation(Tag& tag);//get tag information
extern "C" __declspec(dllexport) int usbDeviceAttached(int waitTime);//initialize usb connect
然后运行程序,可以找到生成的DLL文件。在C#项目中使用,把DLL文件和生成的exe文件放在一起即可,然后C#中添加头部引用:
using System.Runtime.InteropServices;
类中声明:
[DllImport("AS3911Test.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void AS3911FindTag(IntPtr tags, ref int tagNum, int slot); [DllImport("AS3911Test.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool GetTagInformation(ref Tag tag);
[DllImport("AS3911Test.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int usbDeviceAttached(int waitTime);
声明后,可以直接使用这些方法了。不过要注意一点,C#和C++的交互,最麻烦的是数据类型的转换。我这里在参数中使用了Tag这个结构体,在C++中如下:
struct Tag
{
char id[];
char dsfid[];
char afi[];
unsigned int blockNum;
unsigned int bytesPerBlock;
char info[];
};
在C#中对应的声明如下:
public struct Tag
{
/// char[]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = )]
public string id; /// char[]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = )]
public string dsfid; /// char[]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = )]
public string afi; /// unsigned int
public uint blockNum; /// unsigned int
public uint bytesPerBlock; /// char[]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = )]
public string info; }
注意C#中参数部分的ref,相当于C++中指针。涉及到数据类型对应转换时,可以借助CLRInsideOut这个工具。下面以AS3911FindTag(IntPtr tags, ref int tagNum, int slot)这个函数为例,看看如何使用。
static void FindTag()
{
ComInit();
usbDeviceAttached();
ISO15693Init(); int num = ;
int size = Marshal.SizeOf(typeof(Tag)) * Max_Tag_Num;
IntPtr pBuff = Marshal.AllocHGlobal(size);
Tag[] mytag = new Tag[Max_Tag_Num];
AS3911FindTag(pBuff, ref num, ); for (int i = ; i < num; i++)
{
IntPtr p = new IntPtr(pBuff.ToInt64() + Marshal.SizeOf(typeof(Tag)) * i);
mytag[i] = (Tag)Marshal.PtrToStructure(p, typeof(Tag));
Console.WriteLine(mytag[i].id);
} Marshal.FreeHGlobal(pBuff); ISO15693DeInit();
usbDeviceDeAttached();
ComDeInit();
}
直接看到AS3911FindTag(pBuff, ref num, 16)这段代码,这里的pBuff是C#中的引用,然后用Marshal.AllocHGlobal(size)分配了一块内存,传入函数的是一块内存的引用。第二个参数比较简单,表示通过该函数给num赋值。AS3911FindTag这个函数运行完后,pBuff所指向的内存块会被赋值,我们下面就试着取出数据。我们使用了结构体Tag并声明了大小,所以可以从这里着手解决问题。看到for循环中第二行代码,这里的p表示从何处读取数据,最后做类型转换可。Marshal.PtrToStructure这个函数可以将数据从非托管内存块封送到新分配的指定类型的托管对象,这里从DLL中的非托管内存封送到当前C#托管内存。最后,用Marshal.FreeHGlobal(pBuff)释放内存。
C#中使用DLL文件的更多相关文章
- 如何保护.net中的dll文件(防破解、反编译)
如何保护.net中的dll文件(防破解.反编译) 2010-07-19 15:08 [小 大] 来源: 赛迪网 评论: 0 分享至: 百度权重查询 词库网 网站监控 服务器监控 SEO监控 ...
- [转载]解析WINDOWS中的DLL文件---经典DLL解读
[转载]解析WINDOWS中的DLL文件---经典DLL解读 在Windows世界中,有无数块活动的大陆,它们都有一个共同的名字——动态链接库.现在就走进这些神奇的活动大陆,找出它们隐藏已久的秘密吧! ...
- java中调用dll文件的两种方法
一中是用JNA方法,另外是用JNative方法,两种都是转载来的, JNA地址:http://blog.csdn.net/shendl/article/details/3589676 JNativ ...
- 在VC中创建DLL文件的方法步骤
一.Win32动态链接库 1.制作的步骤: (1)新建WIN32 Dynamic-link Library工程,工程名为MyDll,选择A simple DLL project类型. (2)MyDll ...
- 关于vs2012解决方案中项目DLL文件引用问题
今天用vs2012建了项目框架,老是出现说解决方案中的项目dll文件不存在,但是我按照路径去找是可以找到这个文件的,也就是说这个文件存在的.我按照引用顺序单个编译每个项目都是成功的,就是当我编译整个解 ...
- C#中修改Dll文件 (反编译后重新编译)
Dll文件生成后,如没有源代码,又要修改其中内容 可以用微软自带的ildasm和ilasm程序 先用ildasm将dll文件反编译成il文件 ildasm Test.dll /out=Test.il ...
- 如何在 C#中添加 dll 文件
按住鼠标左键,按住dll文件 ,然后将其拖动到工具箱里面 ,就出现了如图所示的控件
- vs2010中添加dll文件
1.更改设置 1.1 project->properties->configuration properties->C/C++->General->Addtional ...
- 关于matlab2014a中生成dll文件,打包成com组件出现的问题和解决方法
问题1:matlab2014a破解不完整,容易导致package打包失败 解决方法:1.下载破解文档:链接: http://pan.baidu.com/s/1eRJ4E2I 密码: 44th 2.下载 ...
随机推荐
- c缺陷与陷阱笔记-第七章 可移植性代码
1.移位运算符 如果被移位的对象长度是n位,那么移位计数必须>=0,并且<n,例如对于1个32位的数,移位运算n<<31和n<<0是OK的,n<<32和 ...
- clone函数
http://blog.csdn.net/caianye/article/details/5947282 http://wenku.baidu.com/link?url=qnq7laYDYm1V8tl ...
- D3D游戏编程系列(一):DXLib的介绍
这篇文章里我准备向大家介绍下我封装的一个基础D3D库:DXLib.有了这样一个类库,可以减少很多无用功以及繁琐的工作,使我们的效率大大提高. DXLib.h #define DIRECTINPUT_V ...
- C# 第三方DLL,可以实现PDF转图片,支持32位系统、64位系统
itextsharp.dll,是一个开源的在C#中用来生成PDF文档的库文件,不少C#爱好者用它制作出了PDF文档生成器.使用时只需在你的C#项目中添加引入此组件即可,使用方法网上有很多,自己查阅一下 ...
- Android开发之布局的学习
FrameLayout-帧布局 实现效果: 代码: <?xml version="1.0" encoding="utf-8"?> <Frame ...
- 1414. Astronomical Database(STL)
1414 破题 又逼着用stl 卡内存 trie树太耗了 水不过去 用set存字符串 set可以自己按一定顺序存 且没有重复的 再用lower_bound二分查找字符串的第一次出现 接着往后找就行了 ...
- openSession()和getCureentSession()的区别
openSession():永远是打开一个新的session getCureentSession():如果当前环境有session,则取得原来已经存在的session,如果没有,则创建一个新的sess ...
- Struts1和Struts2都有什么区别?
总的来说,Struts1 的 Action 是单例模式,因此开发者必须保证它是线程安全的或是同步的,因为Struts 1中每个Action仅有一个实例来处理所有的请求. 但是在用Struts ...
- git恢复被修改的文件
恢复到最后一次提交的改动: git checkout -- + 需要恢复的文件名 但是,需要注意的是,如果该文件已经 add 到暂存队列中,上面的命令就不灵光喽 需要先让这个文件取消暂存: git r ...
- 漫长的补结题报告之路 poj3622
题意(引用):题意:有很多种草,有两个属性:价格和新鲜度:有很多牛,它们都会各自需求一种草,要求是其价格最低为ai,新鲜度最低为bi,且这些牛不希望自己的草和别人的一样.问要满足所有需求的最小花费是多 ...