【发布时间】:2012-10-31 13:20:46
【问题描述】:
我知道这里有一些线程被问到同一主题,但不幸的是没有一个对我有帮助。
我在我的 .net 应用程序中使用非托管 c++ 代码的包装器,在非托管 Dll 中有一个函数“LoadLayoutFile()”,它加载一个带有扩展名 (.lyt) 的自定义格式文件,我的 .net 应用程序有一个循环,它根据数组项计数调用该函数。如果这个数组有一个项目,应用程序运行顺利,没有任何问题,但是如果它有多个项目,应用程序立即崩溃,当然,没有任何机会弄清楚发生了什么,但这也不是所有的时间也是,这非常令人困惑。
我尝试使用 DebugDiag、Windbg 来跟踪崩溃,但没有成功。 我还尝试通过添加析构函数、异常处理来修复我的非托管代码,我还尝试将垃圾收集器(在 .net 应用程序中)放在它们应该在的位置,但这些都不起作用。我很想知道发生了什么事?或者至少能够发现错误!
这是 c++ dll 中的 LoadLayoutFile():
int CMKCRD32App::LoadLayoutFile(LPCSTR lpszFileName)
{
try
{
int nRetVal = MCRC_SUCCESS;
CFile file;
WORD wVersionNumber;
// Add New Layout to the Layouts List
nRetVal = AddLayout();
// If Layout not added Correctly return Error Code
if(nRetVal<0)
return MCRC_MAXLAYOUT_REACHED;
if(file.Open(lpszFileName,CFile::modeRead|CFile::shareCompat))
{
CArchive ar(&file,CArchive::load);
ar >> wVersionNumber;
m_pCard[nRetVal]->Serialize(ar,wVersionNumber);
ar.Close();
file.Close();
m_pCard[nRetVal]->OffsetItemsByMargin(TRUE);
}
else
{
nRetVal = MCRC_ERROROPENFILE;
}
return nRetVal;
}
catch(char *str)
{
throw str;
}
}
AddLayout()
int CMKCRD32App::AddLayout()
{
int nIndex;
try
{
for(nIndex=(_MAX_LAYOUTS_-1); nIndex >= 0; nIndex--)
if(m_pCard[nIndex]==NULL)
break;
if(nIndex>=0)
{
m_pCard[nIndex] = new CLYT_Card();
if(!m_pCard[nIndex])
{
nIndex = -1;
}
}
return nIndex;
}
catch(char *str)
{
throw str;
}
}
这里正是它在 .net 应用程序中崩溃的地方(有时):
CardLayout cardLayout = new CardLayout(); // Wrapper
foreach(var item in x)
int layout = cardLayout.LoadLayoutFile("cc.lyt");
【问题讨论】:
-
LoadLayoutFile的 p/invoke 签名是什么样的?还有应用程序是如何崩溃的?你是遇到异常还是什么? -
@PatrickQuirk 签名是
extern "C" extern int WINAPI MC_LoadLayoutFile(LPCSTR lpszFileName) { CHECK_PROTECT_NOKEY_BOOL; return theApp.LoadLayoutFile(lpszFileName); }没有例外,只是崩溃,它就消失了! -
您使用的是哪个 IDE?在 VS 中,您可以将调试模式设置为“混合”,这样您就可以调试本机代码和托管代码。
-
您能否展示一下 pinvoke 的 C# 端,您在其中定义了一个带有
DllImport属性的extern方法? -
@PatrickQuirk 是的……
[DllImport("MC32.dll")] public static extern int MC_LoadLayoutFile(string lpszFileName);