从Delphi返回动态数组到C#和C++
来源:互联网 发布:诺基亚jar软件下载 编辑:程序博客网 时间:2024/06/05 21:00
经过很多尝试, Delphi/pascal无法将array of integer这样的数组返回给C#,只能传数组的地址过去, C#以IntPtr类型的参数接收, 然后通过Marshal将指针所指的内容复制出来
delphi的dll声明:
function dumpRegisters(out pvOut: PInteger; out pvSize: word): boolean; stdcall;export;begin sendDebug('dumpRegisters.'); result:=false; if (gdm=nil) then begin sendDebug('dumpRegisters, failed'); exit; end; pvOut:=@gdm.FRegisterValues[0]; pvSize:=length(gdm.FRegisterValues); result:=true; sendDebugFmt('dumpRegisters, OK, out:%p, size:%d',[pvOut,pvSize]);end;
C#的import声明:
public static extern void setRoutines(IntPtr pvRoutines); [DllImport("modbusapi.dll", EntryPoint = "dumpRegisters", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern byte dumpRegisters(out IntPtr pvAddr, out UInt16 pvSize);然后通过这个函数转换:
public static int[] IntPtr2RegisterData(IntPtr pvAddr,ushort pvSize) { int[] lvRegisters = new int[pvSize]; Marshal.Copy(pvAddr, lvRegisters,0, pvSize); return lvRegisters; }例子:
IntPtr lvPtr; ushort lvSize; int[] lvRet = null; if (ModBus.dumpRegisters(out lvPtr, out lvSize) != 0) lvRet = ModBus.IntPtr2RegisterData(lvPtr, lvSize); StringBuilder sb = new StringBuilder(); for (int i = 0; i < lvSize; i++) { sb.Append(String.Format("Register:{0}, value: {1}\r\n", i, lvRet[i])); } textBox1.AppendText(sb.ToString()); }
====================
而用VC调用,则可以做到无缝连接,直接引用指针:
定义function指针:
typedef bool(__stdcall* _dumpRegisters)(PINT&, WORD&);
bool ModBus::readRegisters(PINT& pvOut, WORD& pvSize) {if (mHnd == 0) return false;//_dumpRegisters dumpRegisters = (_dumpRegisters)GetProcAddress(mHnd, "dumpRegisters");_dumpRegisters dumpRegisters = (_dumpRegisters)GetProcAddress(mHnd, "dumpRegisters");WORD lvSize = 0;PINT lvAddr = NULL;if (dumpRegisters(lvAddr, lvSize)) {pvOut = lvAddr;pvSize = lvSize;}}调用:
PINT lvRegisters = NULL;WORD lvSize = 0;char lvOut[1024*10];int lvLen = 0;if (modbus.readRegisters(lvRegisters, lvSize)) {for (int i = 0; i < lvSize; i++) {try {lvLen += sprintf_s(lvOut + lvLen, 1024 * 10 - lvLen, "Register:%d, Value:%d \r\n", i, lvRegisters[i]);}catch (const std::exception& e){}}CString lvT(lvOut);ed_log.SetWindowTextW(lvT);}
上述方法应该于内存在dll里面管理的情况, 如果内存块在主程序里面先申请的,调用如下 :
dll 代码:
function dumpRegisters(pvOut: PInteger; out pvSize: word): boolean; stdcall;export;begin sendDebug('dumpRegisters.'); result:=false; if (gdm=nil) then begin sendDebug('dumpRegisters, failed'); exit; end; //pvOut:=@gdm.FRegisterValues[0]; pvSize:=length(gdm.FRegisterValues); sendDebugFmt('dumpRegisters, source addr:%p, target addr:%p,size:%d',[@gdm.FRegisterValues[0],pvOut,pvSize]); sendDebugFmt('before size:%d',[pvSize]); move(gdm.FRegisterValues[0],pvOut^,sizeof(Integer)*pvSize); //复制数据到主程序的内存pvOut sendDebugFmt('after size:%d',[pvSize]); result:=true; sendDebugFmt('dumpRegisters, OK, out:%p, size:%d',[pvOut,pvSize]);end;
VC的调用:
typedefbool(__stdcall* _dumpRegisters)(PINT, WORD&);
_dumpRegisters dumpRegisters = (_dumpRegisters)GetProcAddress(mHnd, "dumpRegisters");PINT lvAddr = NULL;mRegisterSize = mRoutines->getRegisterSize();PINT mRegisters = new int[mRegisterSize];dumpRegisters(mRegisters, pvSize); .....delete [] mRegisters;
C#的调用:
[DllImport("modbusapi.dll", EntryPoint = "dumpRegisters", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] private static extern byte dumpRegisters([In, Out] [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] pvAddr, out UInt16 pvSize);UInt16 lvSize = routines.getResiterSize(); int[] registers = new int[lvSize]; dumpRegisters(registers, out lvSize);
阅读全文
0 0
- 从Delphi返回动态数组到C#和C++
- 从delphi到C++Builder
- 【C++】从函数返回数组
- 从C到C#
- 从C 到 C#
- 从C语言到C++到C#
- 从C转换到到Delphi运算符
- delphi 动态数组和静态数组首地址的区别
- C#返回数组和使用随机函数
- 动态数组介绍----Delphi
- 动态数组介绍----Delphi
- Delphi中的动态数组!
- 动态数组介绍----Delphi
- Delphi动态数组介绍
- Delphi动态数组2
- Delphi 动态数组应用
- Delphi动态数组详解
- Delphi 动态数组
- 豪杰信息杯E-Partial Sum
- vm centos火狐找不到服务器
- USACO
- 搜索--12
- 计算机英语·T
- 从Delphi返回动态数组到C#和C++
- 主线程中同步的 XMLHttpRequest 已不推荐使用,因其对终端用户的用户体验存在负面影响。
- VC链接SQLite的方法
- 浅谈在React中使用Redux数据流(三)
- S5PV210系列 (裸机十一)之 定时器、看门狗和RTC(二)
- y460 win7 关闭小键盘
- Mybatis 自动构建
- Windows中Qt的安装及配置过程(附下载地址)
- 创建长方体通过倒圆变成圆柱