none
C#中结构体中函数指针怎么赋值啊?然后怎么调用啊? RRS feed

全部回复

  • 您好,
    請問您想知道的是「委托(C# 参考)」嗎?

    C#的Delegate的小心得


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/


    2012年3月19日 4:47
  • 是的,但是我在调用的时候不知道出现什么情况?帮忙看一下代码吧

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    namespace epcIsa
    {
    public unsafe delegate uint pfnIsaIobyteR(uint dwIoAddress, byte* pucData);
    public delegate uint pfnIsaIobyteW(uint dwIoAddress, byte ucData);
    public unsafe delegate uint pfnIsaIoWordR(uint dwIoAddress, ushort* pusData);
    public delegate uint pfnIsaIoWordW(uint dwIoAddress, ushort usData);
    public delegate uint pfnIsaInitSysIrq(uint dwIRQNumber,System.IntPtr hIntrEvent,ref uint pdwSysIntr);
    public delegate uint pfnIsaDisableSysIrq(uint dwSysIntrNumber);
    public delegate uint pfnIsaReEnableSysIrq(uint dwSysIntrNumber);
    [StructLayout(LayoutKind.Sequential)]
        public
            struct ZWAPFN
        {
            public pfnIsaIobyteR lpfnIsaIoByteR;                                /*  I/O空间读一字节函数指针        */
            public pfnIsaIobyteW lpfnIsaIoByteW;                                /*  I/O空间写一字节函数指针        */
            public pfnIsaIoWordR lpfnIsaIoWordR;                                /*  I/O空间读一半字函数指针        */
            public pfnIsaIoWordW lpfnIsaIoWordW;                                /*  I/O空间写一半字函数指针        */
            public pfnIsaInitSysIrq lpfnIsaInitSysIrq;                          /*  初始化系统中断函数指针        */
            public pfnIsaDisableSysIrq lpfnIsaDisableSysIrq;                    /*  禁止系统中断函数指针        */
            public pfnIsaReEnableSysIrq lpfnIsaReEnableSysIrq;                  /*  重新使能系统中断函数指针    */
        } ;
    [StructLayout(LayoutKind.Sequential)]
        public
            struct ZWADEVINFO
        {
            public uint dwDevType;                                 /*  设备型号*/
            public uint dwDevAddr;                               /*  设备基地址 */
            public uint dwIrqNo;                       /*  IRQ中断号*/
        } ;
    
    unsafe public partial class epcIsaLib
        {
            [System.Runtime.InteropServices.DllImport("epcIsa", SetLastError = true)]
            public static extern uint epcIsaIoByteR(uint dwIoAddress, byte* pucData);
        } 
    }
    
    
    

    主程序中按钮点击命令代码:

    using System;
    using epcIsa;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    using System.Runtime.InteropServices;
    
    namespace epcIoDemo
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            
            private void deviceOpenButton_Click(object sender, EventArgs e)
            {
                uint dwRet = 0;
                ZWADEVINFO stDevInfo = new ZWADEVINFO();/* 设备信息结构体变量 */
                ZWAPFN stpFnTmp = new ZWAPFN();/* PC/104总线操作函数指针结构体 */
                unsafe
                {
                    
                    uint m_hPCM8208BT;
                    //= (uint )(INVALID_HANDLE_VALUE); /* 接收设备操作句柄 */
                    stDevInfo.dwDevType = (uint)DeviceType.PCM8208BTBS; /* 设备类型号 */
                    stDevInfo.dwDevAddr = (uint)0x200; /* 设备基地址 */
                    stDevInfo.dwIrqNo = (uint)DeviceIRQ.IRQ3; /* 设备使用的IRQ 物理中断号 */
                    stpFnTmp.lpfnIsaIoByteR = new pfnIsaIobyteR(epcIsaLib.epcIsaIoByteR); /* 初始化PC/104 总线操作 */
                    stpFnTmp.lpfnIsaIoByteW = new pfnIsaIobyteW(epcIsaLib.epcIsaIoByteW); /* 接口函数指针 */
                    stpFnTmp.lpfnIsaIoWordR = new pfnIsaIoWordR(epcIsaLib.epcIsaIoWordR);
                    stpFnTmp.lpfnIsaIoWordW = new pfnIsaIoWordW(epcIsaLib.epcIsaIoWordW);
                    stpFnTmp.lpfnIsaInitSysIrq = new pfnIsaInitSysIrq(epcIsaLib.epcIsaInitIntrrupt);
                    stpFnTmp.lpfnIsaDisableSysIrq = new pfnIsaDisableSysIrq(epcIsaLib.epcIsaIntrruptDisable);
                    stpFnTmp.lpfnIsaReEnableSysIrq = new pfnIsaReEnableSysIrq(epcIsaLib.epcIsaIntrruptDone);
                    
                    dwRet = ZwaPCM8208BTBSDrvLib.ZWA_DeviceOpen(ref stDevInfo,ref stpFnTmp, &m_hPCM8208BT );
                }
                if (dwRet != (uint)DeviceErrorCode.ERR_SUCCESS)
                {
                    MessageBox.Show("打开设备失败!");
                }
    
            }
        }
    }
    }

    一旦运行到DeviceOpen时候就会弹出NotSupportedException,不知道哪错了,帮忙看看吧,谢谢了

    任何杀不死我的困难只会让我更强大!!

    2012年3月19日 5:16
  • 您好,

    請問有比較詳細的錯誤訊息嗎?
    NotSupportedException,看來不像是委托的錯誤呢!
    請問您的開發環境是x64嗎?
    您的專案有設成x86運行嗎?


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2012年3月19日 11:07
  • 开发是在WindowsCE上开发的,工具为VS2008,.Compact FrameWork 2.0,难道是调用DLL函数出错了?

    DLL的头文件中函数原型为:

    ZWAPCM8208BTBSDRV_API DWORD ZWA_DeviceOpen(LPZWADEVINFO pstDevInfo

    ,LPZWAPFN pstIsaFn,HANDLE *phDevHandle);



    任何杀不死我的困难只会让我更强大!!


    • 已编辑 杰心 2012年3月19日 12:54
    2012年3月19日 12:53
  • 您好,

    NotSupportedException 类 

    可以試一下,以下的改法! 或是問一下原廠是否有C#的測試Sample哦!

    dwRet = ZwaPCM8208BTBSDrvLib.ZWA_DeviceOpen(ref stDevInfo,ref stpFnTmp, &m_hPCM8208BT );
    =>
    dwRet = ZwaPCM8208BTBSDrvLib.ZWA_DeviceOpen(ref stDevInfo,ref stpFnTmp, ref m_hPCM8208BT );

    另外, m_hPCM8208BT不知要不要改成long,您可能也要Try一下。

    uint m_hPCM8208BT;
    =>
    long m_hPCM8208BT;


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2012年3月19日 22:34
  • 我之前也是过你修改的代码,可是还是一样的提示。

    厂商给的是C++的Sample。。。吐槽无力。。

    您看一下这个C++ Sample的代码,对照一下我改的C#代码,帮忙看一下错误在哪里吧,谢谢了~

    DWORD dwRet = 0;
    ZWADEVINFO stDevInfo; /* 设备信息结构体变量 */
    ZWAPFN stpFnTmp; /* PC/104总线操作函数指针结构体 */
    HANDLE m_ hPCM8208BT; /* 接收设备操作句柄 */
    stDevInfo.dwDevType = PCM8208BT; /* 设备类型号 */
    stDevInfo.dwDevAddr = 0x300; /* 设备基地址 */
    stDevInfo.dwIrqNo = IRQ3; /* 设备使用的IRQ 物理中断号 */
    stpFnTmp.lpfnIsaIoByteR = epcIsaIoByteR; /* 初始化PC/104 总线操作 */
    stpFnTmp.lpfnIsaIoByteW = epcIsaIoByteW; /* 接口函数指针 */
    stpFnTmp.lpfnIsaIoWordR = epcIsaIoWordR;
    stpFnTmp.lpfnIsaIoWordW = epcIsaIoWordW;
    stpFnTmp.lpfnIsaInitSysIrq = epcIsaInitIntrrupt;
    stpFnTmp.lpfnIsaDisableSysIrq = epcIsaIntrruptDisable;
    stpFnTmp.lpfnIsaReEnableSysIrq = epcIsaIntrruptDone;
    dwRet = ZWA_DeviceOpen(&stDevInfo,
    &stpFnTmp,
    &m_hPCM8208BT); /* 打开设备 */
    if (dwRet != ERR_SUCCESS)
     {MessageBox(__T("PCM-8208BT 设备打开失败!"));
    return;
    }


    任何杀不死我的困难只会让我更强大!!

    2012年3月20日 0:54
  • 您顺便帮我看一下DeviceOpen中的两个结构体参数赋值对么?


    任何杀不死我的困难只会让我更强大!!

    2012年3月20日 0:57
  • 下面是错误的详细信息

    未处理 System.NotSupportedException
      Message="NotSupportedException"
      StackTrace:
        位于 epcIoDemo.Form1.deviceOpenButton_Click()
        位于 System.Windows.Forms.Control.OnClick()
        位于 System.Windows.Forms.Button.OnClick()
        位于 System.Windows.Forms.ButtonBase.WnProc()
        位于 System.Windows.Forms.Control._InternalWnProc()
        位于 Microsoft.AGL.Forms.EVL.EnterMainLoop()
        位于 System.Windows.Forms.Application.Run()
        位于 epcIoDemo.Program.Main()
      InnerException:


    任何杀不死我的困难只会让我更强大!!

    2012年3月20日 8:43