问题描述
我有一个带有现有回调处理程序的C dll,该回调处理程序将指针发送到回调函数参数列表和长度中的UInt16数组.
I have a C dll with an existing callback handler that sends a pointer to a UInt16 array in the callback function parameter list and the length.
我有一个C#应用程序(FORM),该应用程序在调用回调时需要接收UInt16数据数据的数组.
I have a C# App (FORM) that needs to recieve the array of UInt16 data data when the callback is called.
它会导致vshost32崩溃,在debuggfer中运行,或者运行几秒钟,然后仅获得0不会获得任何新数据
It crashes vshost32, in debuggfer or It runs for a few seconds then doesnt get any new data just 0's
这取决于我使用IntPtr和Marshal的天气.或将Marshal作为指向secon参数为长度的数组的非托管指针.
This depends on weather I use IntPtr and Marshal.Copy() or Marshal as unmanaged pointer to array with secon param as length.
如果我在调试器中将其停止,第二种方法似乎就可以完美地工作一次,我会得到一个漂亮的1024长度的UInt16数组,看起来像正确的数据.
The second method seems to work perfectly once if i stop it in the debugger I get a nice 1024 length array of UInt16's with what looks likce correct data.
委托代码,用于注册回调的包装器和回调原型
Code for delegate, wrapper for registerinig the callback, and Callback prototype
经过一些失败或崩溃的尝试:
With some iattempts Ive tiied that fail or crash:
//DLL的Calbback函数委托:
//声明委托-定义所需的签名:
//公共委托无效ADCallback(UInt16 [] pBuf,UInt32 BufSize,UInt32标志,UInt32上下文);
//公共委托无效ADCallback(ref UInt16 [] pBuf,UInt32 BufSize,UInt32 Flags,UInt32 Context);
//公共委托void ADCallback(IntPtr pBuf,UInt32 BufSize,UInt32标志,UInt32上下文);
公共委托void ADCallback([[MarshalAs(UnmanagedType.LPArray,SizeParamIndex = 1)] UInt16 [] pBuf,UInt32 BufSize,UInt32标志,UInt32上下文);
//公共委托void ADCallback([MarshalAs(UnmanagedType.LPArray,SizeParamIndex = 1)]
命名空间Sample1
{
公共局部类Form1:Form
{
//Dll回调处理程序导入:
[DllImport("AIOUSB.DLL",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.Cdecl)]
公共静态外部UInt32 ADC_BulkContinuousCallbackStart(UInt32 DeviceIndex,UInt32 BufSize,UInt32 BaseBufCount,UInt32 Context,ADCallback pCallback);
// Calbback function delegate for DLL:
// Declare delegate -- defines required signature:
//public delegate void ADCallback(UInt16[] pBuf, UInt32 BufSize, UInt32 Flags, UInt32 Context);
//public delegate void ADCallback(ref UInt16[] pBuf, UInt32 BufSize, UInt32 Flags, UInt32 Context);
//public delegate void ADCallback(IntPtr pBuf, UInt32 BufSize, UInt32 Flags, UInt32 Context);
public delegate void ADCallback([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] UInt16[] pBuf, UInt32 BufSize, UInt32 Flags, UInt32 Context);
//public delegate void ADCallback([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
namespace Sample1
{
public partial class Form1 : Form
{
// Dll callback handler import:
[DllImport("AIOUSB.DLL", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 ADC_BulkContinuousCallbackStart(UInt32 DeviceIndex, UInt32 BufSize, UInt32 BaseBufCount, UInt32 Context, ADCallback pCallback);
.....然后我在单击按钮时执行此操作:
.....then I do this on a button click:
//用命名方法实例化委托:
ADCallback myCallBack =新的ADCallback(ADCallbackReport);
//GC.KeepAlive(myCallBack);
状态= ADC_BulkContinuousCallbackStart(DeviceIndex,1024,64,0,myCallBack);
// Instantiate delegate with named method:
ADCallback myCallBack = new ADCallback(ADCallbackReport);
//GC.KeepAlive(myCallBack);
Status = ADC_BulkContinuousCallbackStart(DeviceIndex, 1024, 64, 0, myCallBack);
//与委托签名匹配的方法:
//过程ADCallback(pBuf:PWord; BufSize,Flags,Context:LongWord); cdecl;
//公共无效ADCallbackReport(UInt16 [] pBuf,UInt32 BufSize,UInt32标志,UInt32上下文)
//公共无效ADCallbackReport(ref UInt16 [] pBuf,UInt32 BufSize,UInt32标志,UInt32上下文)
//公共无效ADCallbackReport(IntPtr pBuf,UInt32 BufSize,UInt32标志,UInt32上下文)
公共静态无效ADCallbackReport([MarshalAs(UnmanagedType.LPArray,SizeParamIndex = 1)] UInt16 [] pBuf,UInt32 BufSize,UInt32标志,UInt32上下文)
{
// Method that matches delegate signature:
//procedure ADCallback(pBuf: PWord; BufSize, Flags, Context: LongWord); cdecl;
//public void ADCallbackReport(UInt16[] pBuf, UInt32 BufSize, UInt32 Flags, UInt32 Context)
//public void ADCallbackReport(ref UInt16[] pBuf, UInt32 BufSize, UInt32 Flags, UInt32 Context)
//public void ADCallbackReport( IntPtr pBuf, UInt32 BufSize, UInt32 Flags, UInt32 Context)
public static void ADCallbackReport( [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] UInt16[] pBuf, UInt32 BufSize, UInt32 Flags, UInt32 Context)
{
for(int i = 0; i< = 15; i ++)
{
双dVolts = 1/65536 * pBuf [i];
for (int i = 0; i <= 15; i++)
{
double dVolts = 1 / 65536 * pBuf[i];
//如果函数是静态的,则此方法不起作用,因为我不能使用"this"指针???如果不是静态的,它将运行,然后崩溃.
// This doesnt work if the function is static because I cant use the "this" pointer???? It wirks if not static but then crashes.
//现在从线程调用中可以安全地调用它来更新GUI:
//VoltLabel[i].Invoke(new UpdateTextCallback(this.UpdateGUIdata),new object [] {i,dVolts});
}
// Now from the thread call you can safely call this to update GUI:
//VoltLabel[i].Invoke(new UpdateTextCallback(this.UpdateGUIdata), new object[] { i, dVolts });
}
我将尝试进一步澄清,但我落后于进度,超出了预算. :)
I'll try and clarify further but I'm behind schedule and over budget. :)
任何想法都将不胜感激.
Any ideas would be greatly appreciated.
也许我的回调不应该在表单类中?
Maybe my callback shouldn't be in the form class?
谢谢理查德
推荐答案
我正在尝试让一些高级工程师参与此问题,这将需要一些时间.感谢您的耐心配合.
I'm trying to involve some senior engineers into this issue and it will take some time. Your patience will be greatly appreciated.
这篇关于如何将UInt16数组指针传递给C dll回调函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!