在 Windows 2008 中,variant 和 bstr_t 之间的转换导致不一致的崩溃

发布于 2024-08-30 23:35:08 字数 1560 浏览 9 评论 0原文

我们有一个 C# 应用程序,调用一个简单的 C++ 包装类,然后调用现有的 C++ DLL。 C++代码全部是VC++6.0。

我们得到了不一致的行为,但是当崩溃发生时,总是发生在 C++ 包装器 DLL 内,并且总是在同一个位置(已使用痛苦的日志语句确认)。除了 Windows 2008 之外,这种情况在任何环境中都不会发生,因此我们怀疑正在发生一些糟糕但不是致命的内存垃圾,而 Windows 2008 不知何故更加注意了这一点。

这是相关的代码,如果有人对为什么这可能会崩溃有任何想法,我们将不胜感激。我们已经忙了几天了,项目时间表正在推迟,因为我们希望能够将一个简单的字符串返回到 C#...

有人告诉我,我们已经尝试使用 VariantInit 设置 VARIANT vresult ,并在使用 VariantClear 完成后清除它,但这没有帮助。

// JobMgrDll.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "JobMgrDll.h"
#include "jobmgr.h"

CString gcontext;
CString guser;
CString ghost;
CString glog;
JOBMGRDLL_API int nJobMgrDll=0;

extern "C" JOBMGRDLL_API  char*  perform_billcalc(char* cmd, char* context, char* user,char* host,BSTR* log,int* loglen)
{
 char* result = new char[1000];
 memset(result,0,999);
 result[999] = '\0';
 bstr_t bt_command = cmd;

 UUID uuid = __uuidof(BRLib::Rules);
 VARIANT vresult;
 char *p_rv;
 gcontext = context;
 guser = user;
 ghost = host;
 write_log("execute_job");
 p_rv = execute_job(uuid, "none", bt_command, &vresult);
 write_log("DONE execute_job");
 CString message;

 write_log ("Intializing bstr_t with variant");  // WE ALWAYS GET HERE
 bstr_t res(vresult); 

 //message.Format("%s result = %s",p_rv,res);
 //write_log(message);
 write_log("copying Result");  // WE DON'T ALWAYS GET HERE, BUT SOMETIMES WE DO
 strcpy(result,(char*)res);
 write_log(CString(result));

 *loglen = glog.GetLength();
 *log = glog.AllocSysString();

 return result;
}

再次强调,任何想法都非常非常感谢。

We have a C# application, calling a simple C++ wrapper class, that then calls an existing C++ DLL. The C++ code is all VC++ 6.0.

We are getting inconsistent behaviour, but the crash, when it happens, always happens within the C++ wrapper DLL, and always in the same spot (have confirmed using painful logging statements). It never happens on any environment except on Windows 2008, so we suspect some bad-but-not-fatal memory trashing is going on that somehow Windows 2008 is being more mindful of.

Here's the relevant code, if anyone has any ideas on why this might be crashing it would be much appreciated. We've been tearing our hair out for a few days and project timelines are slipping all for the want of being able to return a simple string back to C#...

I've been told we've tried setting the VARIANT vresult using VariantInit, and clearing it when we are done with VariantClear, but that didn't help.

// JobMgrDll.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "JobMgrDll.h"
#include "jobmgr.h"

CString gcontext;
CString guser;
CString ghost;
CString glog;
JOBMGRDLL_API int nJobMgrDll=0;

extern "C" JOBMGRDLL_API  char*  perform_billcalc(char* cmd, char* context, char* user,char* host,BSTR* log,int* loglen)
{
 char* result = new char[1000];
 memset(result,0,999);
 result[999] = '\0';
 bstr_t bt_command = cmd;

 UUID uuid = __uuidof(BRLib::Rules);
 VARIANT vresult;
 char *p_rv;
 gcontext = context;
 guser = user;
 ghost = host;
 write_log("execute_job");
 p_rv = execute_job(uuid, "none", bt_command, &vresult);
 write_log("DONE execute_job");
 CString message;

 write_log ("Intializing bstr_t with variant");  // WE ALWAYS GET HERE
 bstr_t res(vresult); 

 //message.Format("%s result = %s",p_rv,res);
 //write_log(message);
 write_log("copying Result");  // WE DON'T ALWAYS GET HERE, BUT SOMETIMES WE DO
 strcpy(result,(char*)res);
 write_log(CString(result));

 *loglen = glog.GetLength();
 *log = glog.AllocSysString();

 return result;
}

Again, any ideas much, much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柒夜笙歌凉 2024-09-06 23:35:08

堆和堆栈损坏的机会比比皆是。不初始化变体无异于自杀。将 C 字符串复制到本地 char[] 而不检查长度希望总是幸运的。真正的损害可能发生在任何地方,execute_job() 或半小时前运行的东西。

考虑使用一个工具来捕获此类错误,例如 Coverity。

The opportunities for heap and stack corruption abound. Not initializing the variant is suicidal. Copying a C string into a local char[] without checking the length is hoping to always be lucky. The real damage could be done anywhere, execute_job() or something that ran half an hour ago.

Consider a tool to catch mistakes like these, something like Coverity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文