从非托管代码回调到托管

编程入门 行业动态 更新时间:2024-10-28 00:18:13
本文介绍了从非托管代码回调到托管的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在触发我的托管代码并启动对非托管代码的调用.非托管代码中有回调.从非托管中,我在托管方法DelegateMethod"中收到回调.但是我没有从非托管代码中获得正确的参数/参数值.请帮我解决这个问题

I am triggering my managed code and initiating a call to unmanaged code. There is a callback in unmanaged code. From unmanaged I am getting callback in my managed method 'DelegateMethod'. But I am not getting proper parameter/argument values from unmanaged code. Please help me with this

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace TestApp { public class Program { public delegate void fPointer(byte[] Sendapdu, ref int Sendlen, byte[] Recvapdu, ref int Recvlen); public struct sCommsAbstraction { ///Function to send and receive. public fPointer pf_TxRx; ///Other functions if necessary, e.g. reset } // Create a method for a delegate. public static void DelegateMethod(byte[] Sendapdu, ref int Sendlen, byte[] Recvapdu, ref int Recvlen) { //This is called from unmanaged code. I am not getting proper arguments Console.WriteLine(Sendlen); } [DllImport("AuthLibrary.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int CmdLib_RegisterItsIO(ref sCommsAbstraction psCommsFunctions); [DllImport("AuthLibrary.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int CmdLib_OpenApplication(); [DllImport("TransparentChannel.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int TC_Transceive(byte[] writeBuf, ref int writeBufLen, byte[] readBuf, ref int pwReadBufferLen); static void Main(string[] args) { sCommsAbstraction psCommsFunctions = new sCommsAbstraction(); // Instantiate the delegate. psCommsFunctions.pf_TxRx = DelegateMethod; CmdLib_RegisterItsIO(ref psCommsFunctions); CmdLib_OpenApplication(); } } }

我的无人管理的代码出现在这里 - CmdLib.c

My unmanged piece of code is present here - CmdLib.c

//C code - unmanaged typedef int32_t (*pFTransceive)(const uint8_t *prgbWriteBuffer, const uint16_t *pwWriteBufferLen, uint8_t *prgbReadBuffer, uint16_t *pwReadBufferLen); typedef struct sCommsAbstraction { ///Function to send and receive. pFTransceive pf_TxRx; ///Other functions if necessary, e.g. reset }sCommsAbstraction_d static sCommsAbstraction_d sCommsAbstraction = {0}; void CmdLib_RegisterItsIO(const sCommsAbstraction_d *psCommsFunctions) { sCommsAbstraction.pf_TxRx = psCommsFunctions->pf_TxRx; } void CmdLib_OpenApplication() { sCommsAbstraction.pf_TxRx(rgbAPDUBuffer,&wTotalLength,rgbAPDUBuffer,&psApduData->wResponseLength); }

推荐答案

您的委托声明与 pFTransceive 函数指针声明不匹配.这会在您的回调方法中产生垃圾参数值.

Your delegate declaration is not a match for the pFTransceive function pointer declaration. Which produces garbage argument values in your callback method.

靠近:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void fPointer( [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] Sendapdu, ref short Sendlen, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] Recvapdu, ref short Recvlen );

注意 必需 属性以匹配 C/C++ 程序中使用的默认调用约定.和 short 参数类型匹配 uint16_t.`

Note the required attribute to match the default calling convention that's used in C/C++ programs. And the short argument types to match uint16_t.`

更多关于这篇文章.

sCommsAbstraction psCommsFunctions = new sCommsAbstraction();

这是您必须担心的另一件事.只要本机代码可以进行回调,该对象就需要继续存在.现在它没有,下一次垃圾收集将销毁它,因为垃圾收集器无法发现本机代码正在使用它.Kaboom 当本机代码进行回调时.您还没有看到那个错误,调试器现在使对象保持活动状态.这不会在生产中发生.

This is another thing you have to fret about. That object needs to survive as long as the native code can make callbacks. Right now it doesn't, the next garbage collection is going to destroy it since the garbage collector has no way to find out that the native code is using it. Kaboom when the native code makes the callback. You are not seeing that bug yet, the debugger keeps the object alive right now. That is not going to happen in production.

如所写,您需要将此语句添加到 Main() 方法的底部:

As written, you need to add this statement to the bottom of your Main() method:

GC.KeepAlive(psCommsFunctions);

将它存储在 static 变量中是更好的方法,只有当您知道本机代码不会这样做时才将其设置回 null不再进行回调.

Storing it in a static variable is the better approach, only ever set it back to null when you know for a fact that the native code isn't going to make callbacks anymore.

更多推荐

从非托管代码回调到托管

本文发布于:2023-11-02 18:08:31,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1553054.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:回调   代码

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!