我正在开发一个具有一些 COM 接口(interface)的 API。问题在于 API 通过一个接口(interface)进行通信,该接口(interface)必须由加载该 API 的项目实现。因此,如果我要使用 API,我会将其加载到我的项目中并创建一个类来实现 API 调用的方法,以通知我某些事情或向我传递结果。
这显然成为编码噩梦。此外,由于还有一些中间对象通过 API 从不同的插件和管理器将调用传递给所有实现要为通知调用的方法的对象,这些对象已将自己注册到 API 通知程序,这在术语上已经失控了的复杂性。
我在想,为了缩短加载API的人需要完成的工作,如果API遵循自由线程模型,MFC生成的类如对话框是否可以实现通知需要 COM 接口(interface)?请记住,需要将此类对象转换为 IStream,然后再转换回 API 端的接口(interface),以便 API 可以调用这些方法。
据我所知,MFC 对话框默认是 STA。有什么方法可以强制他们更改或开始使用 MTA?从 COM 的角度来看,它是否合法?我试图避免创建另一个对象来处理另一个线程中的通知,因为这会使事情复杂化。此 API 需要在多个地方使用,有时在 GUI 中,有时在服务中等。
最佳答案
我的理解是,API 本身并不限于控制线程,您的意图是通过 COM 接收器接口(interface)在后台线程上获取通知。
有几种方法可以解决同时保持 COM 友好的问题。最简单的方法是更改应用程序的全局单元模型,以便将“主”GUI 线程初始化为 MTA。虽然这可能有效,但您可能很快就会发现这与其他东西不兼容,例如使用“Arartment”线程模型注册的 ActiveX 控件。
另一种选择是稍微违反 COM 线程准则,这样 API 就可以直接从后台线程使用接收器接口(interface),而无需对其进行编码(marshal)处理。这将与准备好接收侧线程调用的 MFC 应用程序一起正常工作,并且实际上很容易做到(只需在 API 侧的线程/单元之间自愿传递接收器接口(interface)指针)。当检测跨单元接口(interface)指针使用的 .NET 客户端使用 API 时,稍后可能会出现此问题。
为了使其对 COM 友好并且在 UI 线程上仍然使用 STA 线程,您可以实现以下方案。 API可以是接受直接传入sink接口(interface)的STA组件(STA中MFC类实现的COM对象,或者更简单的如直接在window类上实现的COM接口(interface)等)。 API 编码将接口(interface)指针汇入 MTA 以供工作线程使用(CoMarshalInterThreadInterfaceInStream 和 friend )。 API 使用未编码的指针从 MTA 线程传递通知。这通常包括 threda 切换到您不想要的原始线程,因此为了避免它,MFC 端通知类应该实现自由线程编码(marshal)拆收器。这将改变一些事情,以便未编码的接口(interface)指针直接在工作线程上接收调用,而 MFC 应用程序将负责线程同步(关键部分等)。这是 STA、COM 友好的 API 工作线程,同时高效。
关于c++ - 将 MFC 对话框从 STA 更改为 MTA?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18888243/
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe
假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功
我想在IRB中浏览文件系统并让提示更改以反射(reflect)当前工作目录,但我不知道如何在每个命令后进行提示更新。最终,我想在日常工作中更多地使用IRB,让bash溜走。我在我的.irbrc中试过这个:require'fileutils'includeFileUtilsIRB.conf[:PROMPT][:CUSTOM]={:PROMPT_N=>"\e[1m:\e[m",:PROMPT_I=>"\e[1m#{pwd}>\e[m",:PROMPT_S=>"FOO",:PROMPT_C=>"\e[1m#{pwd}>\e[m",:RETURN=>""}IRB.conf[:PROMPT_MO