【发布时间】:2015-05-26 15:06:38
【问题描述】:
我创建了一个使用 2 个 C++ Dll 的 C# 应用程序,第一个运行良好,但第二个遇到了一些问题。
我正在刷 CPU:
我的 dll:
[DllImport(@"st10flasher.dll")]
public static extern long SetCom(string PortName, long comspeed);
[DllImport(@"st10flasher.dll")]
public static extern long LoadFile(string FileName, ref long Fsize);
[DllImport(@"st10flasher.dll")]
public static extern long InitMonitor(string device);
[DllImport(@"st10flasher.dll")]
public static extern long ProgramFlash();
[DllImport(@"st10flasher.dll")]
public static extern long EraseFlash(long Block);
[DllImport(@"st10flasher.dll")]
public static extern long CloseCom();
[DllImport(@"st10flasher.dll")]
public static extern long BlockNBToErase(bool EraseBlockError);
它通常可以工作,但有时会崩溃。 -我检查了事件日志,发现异常代码:0xc0000409 - 它问我是否想用 VS 调试它然后我有这个堆栈:
错误消息不是英文的,我会尝试翻译: 非托管异常 0x71E2CF1B (clr.dll)。检测到的检测代码堆栈 cookie 超出堆栈缓冲区
可能是什么?谢谢 !
正如你所问,我添加了 VB 声明:
Declare Function SetCom Lib "st10flasher.dll" (ByVal PortName$, ByVal comspeed As Long) As Long
Declare Function LoadFile Lib "st10flasher.dll" (ByVal FileName$, ByRef Fsize As Long) As Long
Declare Function InitMonitor Lib "st10flasher.dll" (ByVal device As Any) As Long
Declare Function ProgramFlash Lib "st10flasher.dll" () As Long
Declare Function GetError Lib "st10flasher.dll" (ByVal BufferForStatus As Any) As Long
Declare Function EraseFlash Lib "st10flasher.dll" (ByVal Block As Long) As Long
Declare Function CloseCom Lib "st10flasher.dll" () As Long
/**************************************************** **** 编辑 ********************************************* *****/
所以我更新了我的函数声明:
[DllImport(@"st10flasher.dll")]
public static extern uint SetCom([MarshalAs(UnmanagedType.LPStr)] string PortName, uint comspeed);
[DllImport(@"st10flasher.dll")]
public static extern uint LoadFile([MarshalAs(UnmanagedType.LPStr)] string FileName, ref uint Fsize);
[DllImport(@"st10flasher.dll")]
public static extern uint InitMonitor([MarshalAs(UnmanagedType.LPStr)] string device);
[DllImport(@"st10flasher.dll")]
public static extern uint ProgramFlash();
[DllImport(@"st10flasher.dll")]
public static extern uint EraseFlash(uint Block);
[DllImport(@"st10flasher.dll")]
public static extern uint CloseCom();
[DllImport(@"st10flasher.dll")]
public static extern uint BlockNBToErase(bool EraseBlockError);
我找到了 dll 的文档:
unsigned int SetCom(char *PortName, unsigned int ComSpeed)
unsigned int CloseCom(void)
unsigned int LoadFile(char *filename)
unsigned int InitMonitor(char *target)
unsigned int EraseFlash(unsigned int BlockMask)
unsigned int ProgramFlash(void)
我尝试使用这篇文章更新我的原型:post StackOverflow 但我仍然有同样的错误。我是否误解了链接中的某些内容?
/******************************解决*************** *************/
我通过创建另一个加载和卸载 st10flasher.dll 的 C++ DLL 解决了我的问题
【问题讨论】:
-
一切...例如,您没有使用
CallingConvention.Cdecl...您的pinvoke方法是Stdcl吗?所有的参数和返回值都正确吗?没有.h文件,我们怎么知道? -
请注意,我很少看到
long在 C 库中使用...在 C for Windows 中,sizeof(long) == sizeof(int),所以除非在 C 中它是long long int或int64_t,那么你应该使用int -
我们需要看到双方。您只向我们展示了 C# 代码 -- 向我们展示了 C++ 声明。
-
异常 0xc0000409 非常非常讨厌。堆栈跟踪显示它发生在垃圾收集器运行时。这是一个非常强烈的暗示,表明 GC 堆已损坏。堆损坏通常是由错误的 pinvoke 引起的。你显然在这里有一个强有力的候选人。您展示的方法中没有灌篮,但 long 不太可能是正确的。 C 或 C++ 代码中的 long 是 .NET 中的 int。
-
@PyNico
I *think* parameters are ok这就是为什么你应该展示你的 C++ 函数是如何声明的。如果调用约定、返回类型和参数类型关闭,您的函数将无法正常工作。
标签: c# c++ dll marshalling vhosts