使用DLLImport函数时程序崩溃

时间:2019-07-03 14:32:55

标签: c# c++ callback pinvoke dllimport

我正在尝试使用来自C ++ dll的函数,该函数设置了将来可以在程序中使用的回调,但是当我调用该函数时,应用程序崩溃而没有显示错误或任何内容。

C#代码:


        [DllImport("DocProc.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public static extern ulong DPSetCallBacks(DPHandle hdl, IntPtr cbs);

        public delegate void ConnectedCB(DPHandle hdl);
        public delegate void DisconnectedCB(DPHandle hdl);
        public delegate void DocCompleteCB(DPHandle hdl);
        public delegate void DocImageCompleteCB(DPHandle hdl);
        public delegate void DocImageSnippetCompleteCB(DPHandle hdl);
        public delegate void DocReadCompleteCB(DPHandle hdl);
        public delegate void ExceptionCompleteCB(DPHandle hdl);
        public delegate void ExceptionInProgressCB(DPHandle hdl);
        public delegate void FlowStoppedCB(DPHandle hdl);
        public delegate void HopperEmptyCB(DPHandle hdl);
        public delegate void IdleCB(DPHandle hdl);
        public delegate void MachineDeadCB(DPHandle hdl);
        public delegate void PoweredDownCB(DPHandle hdl);
        public delegate void PoweredUpCB(DPHandle hdl);
        public delegate void PoweringUpCB(DPHandle hdl);
        public delegate void ReadyingCB(DPHandle hdl);
        public delegate void ReadyToProcessCB(DPHandle hdl);
        public delegate void StateExceptionCB(DPHandle hdl);
        public delegate void WarningCB(DPHandle hdl);
        public delegate void NvmReadCompleteCB(DPHandle hdl);
        public delegate void MakeReadyToFlowCompleteCB(DPHandle hdl);

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
        public struct DPcbs
        {
            public int size;
            public ConnectedCB connectedCB;
            public DisconnectedCB disconnectedCB;
            public DocCompleteCB docCompleteCB;
            public DocImageCompleteCB docImageComplete;
            public DocImageSnippetCompleteCB docImageSnippetCompleteCB;
            public DocReadCompleteCB docReadComplete;
            public ExceptionCompleteCB exceptionCompleteCB;
            public ExceptionInProgressCB exceptionInProgressCB;
            public FlowStoppedCB flowStoppedCB;
            public HopperEmptyCB hopperEmptyCB;
            public IdleCB idleCB;
            public MachineDeadCB machineDeadCB;
            public PoweredDownCB poweredDownCB;
            public PoweredUpCB poweredUpCB;
            public PoweringUpCB poweringUpCB;
            public ReadyingCB readyingCB;
            public ReadyToProcessCB readyToProcessCB;
            public StateExceptionCB stateExceptionCB;
            public WarningCB warningCB;
            public NvmReadCompleteCB nvmReadCompleteCB;
            public MakeReadyToFlowCompleteCB makeReadyToFlowCompleteCB;
        }

C ++代码:

typedef struct { 
unsigned int size;
 ConnectedCB connectedCB;
 DisconnectedCB disconnectedCB;
 DocCompleteCB docCompleteCB;
 DocImageCompleteCB docImageComplete;
 DocImageSnippetCompleteCB docImageSnippetCompleteCB;
 DocReadCompleteCB docReadComplete;
 ExceptionCompleteCB exceptionCompleteCB;
 ExceptionInProgressCB exceptionInProgressCB;
 FlowStoppedCB flowStoppedCB;
 HopperEmptyCB hopperEmptyCB;
 IdleCB idleCB;
 MachineDeadCB machineDeadCB;
 PoweredDownCB poweredDownCB;
 PoweredUpCB poweredUpCB;
 PoweringUpCB poweringUpCB;
 ReadyingCB readyingCB;
 ReadyToProcessCB readyToProcessCB;
 StateExceptionCB stateExceptionCB;
 WarningCB warningCB; 
 NvmReadCompleteCB nvmReadCompleteCB;
 MakeReadyToFlowCompleteCB makeReadyToFlowCompleteCB;
}

unsigned long DPSetCallBacks(DPHandle hdl, DPcbs *dpcbs);

我这样使用它:

 DPcbs cbs = new DPcbs();
               cbs.poweredUpCB = PoweredUp;

                ptr = Marshal.AllocHGlobal(Marshal.SizeOf(cbs));
                try
                {

                    // Copy the struct to unmanaged memory.
                    Marshal.StructureToPtr(cbs, ptr, false);

                    DPSetCallBacks(handle, ptr);

                }
                finally
                {
                    // Free the unmanaged memory.
                    Marshal.FreeHGlobal(ptr);
                }

结果是应用程序崩溃而没有任何可见的错误。任何帮助将不胜感激。预先感谢!

1 个答案:

答案 0 :(得分:-1)

如果要在DLL中编译此类C ++代码,最好将其包含在类中并提供访问器方法。

c#项目如果不包装就永远无法访问已编译的typedef结构!

请注意您的运行时编译的DLL版本