我在一个具有GUI(图形)和API(脚本)接口的应用程序上工作.我们的产品具有非常大的安装基础.许多客户在编写使用我们产品的脚本上投入了大量的时间和精力.
在我们的所有设计和实现中,我们(可以理解)对保持100%向后兼容性有非常严格的要求.当我们引入新的软件版本时,之前运行的脚本必须以完全相同的方式继续运行,无需任何修改.
不幸的是,这种要求有时会牵扯到我们的背后,因为它确实限制了我们的创新能力,并提出了新的更好的做事方式.
例如,我们可能会提出一种更好(更有用)的方法来实现已经可能的任务.我们希望以更好的方式使用默认方式,但我们不能这样做,因为它可能具有向后兼容性含义.因此,我们坚持将新的(更好的)方式作为一种模式,用户必须在其可用之前"打开".除非他们阅读文档或在线帮助(许多客户不这样做),否则这项新功能将永远隐藏起来.
我知道Windows Vista在第一次出现时会让很多人感到恼火,因为所有软件和外围设备都没有用,即使他们在XP上工作也是如此.由于这个原因,它收到了非常糟糕的接待.但是你可以看到,微软也成功地在Vista中进行了一些伟大的创新,但却牺牲了许多用户的向后兼容性.他们冒了风险.它得到了回报吗?他们做出了正确的决定吗?我想只有时间会证明.
您是否发现自己在平衡创新和向后兼容性的冲突需求?你如何处理杂耍行为?
我正在调试一个缺陷,并将其缩小到对象的vtable指针0xdddddddd. 这个答案表明Win32调试版本通常会将死记忆或已删除的内存设置为此特殊值.
需要注意的是指针本身看起来有效,它只是虚函数表指针是0xdddddddd.
这是一段代码:
std::list<IMyObject*>::const_iterator it;
for (it = myObjects.begin(); it != myObjects.end(); ++it)
{
IMyObject* pMyObject = *it;
if (pMyObject == 0)
continue;
pMyObject->someMethod(); // Access violation
}
Run Code Online (Sandbox Code Playgroud)
如果我在访问冲突的行中断并观察pMyObject,我可以看到它pMyObject本身有一个有效的地址(0x08ede388)但该__vfptr成员是无效的(0xdddddddd).
一些说明:
有关如何进一步调试的任何建议?
我最近不得不为同事开发的现有服务开发一个额外的模块.他在主要工作函数中放置了一个try/catch块,用于捕获冒泡到这个级别的所有未处理异常,将它们与堆栈跟踪信息一起记录下来:
try
{
// do main work
}
catch(Exception ex)
{
// log exception info
}
Run Code Online (Sandbox Code Playgroud)
虽然这使程序非常稳定(如'不太可能崩溃'),但我讨厌它,因为当我测试我的代码时,我没有看到由它引起的异常.当然,我可以查看异常日志并查看是否有新条目,但我非常喜欢在抛出异常时获得异常的直接反馈(请将光标放在代码的右侧).
我至少在编码和测试的时候删除了这个顶级的try/catch.但是现在我的任务已经完成,我必须决定是否将其重新用于发布,或者不是.我认为我应该这样做,因为它使服务更稳定,而且它的全部意义在于它在后台运行而无需任何监督.另一方面,我已经读过一个应该只调用特定的异常(如IoException),而不是一般Exception.
你对这个问题有什么建议?
顺便说一句,该项目是用C#编写的,但我也对非.NET语言的答案感兴趣.
在我工作的一些IDL中,我注意到在方法中有两种用于标记返回值的约定 - [in, out]和[out, retval].
似乎[in, out]在有多个返回值时使用,例如:
HRESULT MyMethod(
[in] long InputParam,
[in, out] long* OutputParam1,
[in, out] long* OutputParam2
);
Run Code Online (Sandbox Code Playgroud)
似乎[out, retval]只有一个返回值时使用,例如:
HRESULT MyMethod2(
[in] long InputParam,
[out, retval] long* OutputParam1
);
Run Code Online (Sandbox Code Playgroud)
这是一个COM IDL约定还是我正在使用的代码中的约定?
从2个符号生成的代码是否存在功能差异,或者它们是否完全可互换?
在软件开发过程中,代码库中可能存在已知问题的错误.如果测试编写良好,这些错误将导致回归/单元测试失败.
我们的团队一直在争论如何管理失败的测试:
使用REVISIT或TODO注释评论失败的测试用例.
让测试用例失败.
我想探讨一下这方面的最佳实践.就个人而言,我认为三态解决方案最适合确定脚本是否正在通过.例如,当您运行脚本时,您可以看到以下内容:
您基本上可以使用某些元数据标记您希望失败的测试用例(由于某些缺陷).这可以确保您在测试结束时仍然可以看到失败结果,但会立即知道是否有新的结果您不期望故障.这似乎采取了上述两个提案中最好的部分.
有没有人有任何最佳实践来管理这个?
我班上有几个成员,const因此只能通过初始化列表进行初始化,如下所示:
class MyItemT
{
public:
MyItemT(const MyPacketT& aMyPacket, const MyInfoT& aMyInfo)
: mMyPacket(aMyPacket),
mMyInfo(aMyInfo)
{
}
private:
const MyPacketT mMyPacket;
const MyInfoT mMyInfo;
};
Run Code Online (Sandbox Code Playgroud)
我的类可以在我们的一些内部定义的容器类(例如向量)中使用,并且这些容器需要operator=在类中定义.
当然,我operator=需要做这样的事情:
MyItemT&
MyItemT::operator=(const MyItemT& other)
{
mMyPacket = other.mPacket;
mMyInfo = other.mMyInfo;
return *this;
}
Run Code Online (Sandbox Code Playgroud)
这当然不起作用,因为mMyPacket并且mMyInfo是const成员.
除了让这些成员不是const(我不想做),关于如何解决这个问题的任何想法?
我正在尝试调试使用OutOfMemoryException时创建相当大的ZIP文件时发生的情况System.IO.Packaging.ZipPackage.
代码遍历大型对象列表,为每个对象执行以下操作.
PackagePart为文件创建一个.System.IO.Stream到另一个:
FileStreamPackagePart::GetStream()=>MS.Internal.IO.Zip.ZipIOModeEnforcingStream最后它调用Package::Close()保存文件.
我遇到的问题是,对于一个特别大的对象列表,我看到了OutOfMemoryException(x86进程大小增加到大约1.2GB).
我正在考虑将对象数据划分为块,所以我每个循环只处理一个较小的量(即上面的步骤1-3).我的想法是,我将n在一个临时目录中创建ZIP文件,然后找到一种方法将它们组合成一个存档.
这可能用System.IO.Packaging吗?我会用什么来组合这些部件?
或者有更好的方法来解决这个问题吗?
TortoiseSVN在Windows资源管理器中显示图标装饰,显示特定目录树中是否存在任何未提交的更改.例如:

上图显示目录树中某处Trunk有更改的文件.
但是,我经常使用ignore-on-commit更改列表来保存我从未想要提交的Web.config更改- 例如,与连接字符串相关的更改.
我不能依靠图标装饰让我知道我是否有变化,因为它们也会出现红色(!),即使只有Web.config变化.这会给Explorer带来不必要的噪音.
有没有办法改变这个,以便只有我想要提交的更改被标记为资源管理器中的更改?
大多数关于虚拟内存的文献都指出,作为一名应用程序开发人员,了解虚拟内存可以帮助我利用其强大的功能.我曾经参与过在Linux上开发应用程序,但在编写代码时并不关心虚拟内存的复杂性.我错过了什么吗?如果是这样,请详细说明我如何利用虚拟内存的工作原理.如果我对这个问题没有意义,请告诉我!
我试图使用Visual Studio 2005中的ATL简单对象向导在我的DLL中创建一个新的COM对象.
我输入对象的短名称,并导出所有其他字段.
但是,当我在向导中单击" 下一步 "时,会出现以下错误消息:
Object 'IXxxInterfaceName' already exists
Run Code Online (Sandbox Code Playgroud)
我已经搜索了我的整个解决方案,以获取对IXxxInterfaceName的所有引用,并且无法在任何地方看到它的定义.
向导如何确定它已经存在?