使用 DLLImport 函数时程序崩溃
Posted
技术标签:
【中文标题】使用 DLLImport 函数时程序崩溃【英文标题】:Program crash when using DLLImport function 【发布时间】:2019-07-03 14:32:55 【问题描述】:我正在尝试使用 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);
结果是应用程序崩溃而没有任何可见的错误。任何帮助将不胜感激。提前致谢!
【问题讨论】:
如果没有错误,你的意思是它崩溃了?我没有看到您正在执行任何类型输出的任何代码,所以它不能成功完成吗?你的意思是控制台窗口正在关闭?在 C# 程序的末尾添加Console.ReadLine()
。
这是一个 Windows 窗体应用程序,只要运行该函数,应用程序就会退出。
垃圾收集器可能以某种方式运行,当从托管代码调用时,您的托管指针消失了。可能与此重复:***.com/questions/4906931/…
嗯,这与我正在做的事情有点不同......
C# ulong
是 64 位,C++ unsigned long
是 32 位。缺少大量关键代码部分,这可能是问题的原因。我们不知道调用约定是否匹配,代理是否受到保护以防收集,此外可能还有更多潜在的陷阱。不幸的是,pinvoke 问题缺少关键细节是很常见的。
【参考方案1】:
如果您想在 DLL 中编译此类 C++ 代码,最好将其包含在类中并提供访问器方法。
如果不包装,c# 项目永远无法访问已编译的 typedef 结构!
注意您的运行时编译的 DLL 版本
【讨论】:
我真的不明白你的意思,你能澄清一下吗?谢谢。 那么,这究竟是如何回答这个问题的呢?以上是关于使用 DLLImport 函数时程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章