网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > .Net >

C#调用c语言dll,并且传入byte数组或字符串,简单

时间:2024-12-20 18:47

人气:

作者:admin

标签:

导读:前言 在C#中调用dll,可能会出现程序一开始可以运行,但过一会儿后出现内存错误——尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 这是由于C#的托管内存机制,而C语言...

前言

在C#中调用dll,可能会出现程序一开始可以运行,但过一会儿后出现内存错误——尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
这是由于C#的托管内存机制,而C语言中是非托管内存。如果参数传入dll后,C#提前回收了内存或者移动了数据,将会出现错误。
解决方法是,在C#传入dll参数之前,将托管内存中的数据移动到非托管内存中,然后传入非托管内存的地址。(同理我们需要在dll中函数执行完后,手动释放非托管内存)、

静态路径调用dll

使用DllImport即可

const string zlg1939Dllpath = "C:\\projects\\自动测试\\zlgcanj1939\\Debug\\zlgcanj1939.dll";
[DllImport(zlg1939Dllpath, CallingConvention = CallingConvention.Cdecl)]
public static extern uint zlgcanInit(IntPtr dllDirectory, uint baurdrate);

[DllImport(zlg1939Dllpath, CallingConvention = CallingConvention.Cdecl)]
public static extern int zlgcanSendOneMessage(uint id, IntPtr data, byte datanum);

参数传入

核心思想是,使用Marshal类,开辟非托管的内存空间,然后向dll传入指针。
下面例举的C语言函数原型为:

int zlgcanInit(char* dllDirectory, uint32_t baurdrate, uint32_t device_index, uint32_t can_index);
int zlgcanSendOneMessage(uint32_t id, uint8_t* data, uint8_t datanum);

字符串

// 参数声明使用 IntPtr dllDirectory
// public static extern uint zlgcanInit(IntPtr dllDirectory, uint baurdrate);
// 参数传入使用 Marshal.StringToHGlobalAnsi(zlgwrapDllpath)
zlgcanInit(Marshal.StringToHGlobalAnsi(zlgwrapDllpath), 250000);

简单类型数组(例如byte数组)

// 参数声明使用 IntPtr data
// public static extern int zlgcanSendOneMessage(uint id, IntPtr data, byte datanum);
// 指向非托管内存的指针
IntPtr dataptr = Marshal.AllocHGlobal(8 * sizeof(byte));
// 托管内存中的数组
byte[] data = { 0, 0, 0, 4, 5, 0, 0, 0 };
// 内存复制
Marshal.Copy(data, 0, dataptr, 8);
// 调用
zlgcanSendOneMessage(0xcf00400, dataptr, 8);

释放内存

Marshal.FreeHGlobal(IntPtr);
温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信