- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在初始化线程中打开 Matlab 引擎,执行以下操作:
bool MY_MATLAB_ENGINE_o::Open()
{
// Handle the case where engine is already open
if( MatlabEngine )
{
return true;
}
else if( !( MatlabEngine = engOpen( 0 ) ) )
{
return false;
}
IsEngineOpen.SetValue( true );
return true;
}
函数 engOpen()
打开一个到 Matlab 的 COM channel 。一旦引擎打开,线程就会进入等待事件模式。
然后,在另一个线程中,我这样做:
bool MY_MATLAB_ENGINE_o::ChangeDirectory( QString strPath )
{
QString strPathToScript = "cd('" + strPath + "');";
QByteArray ba = strPathToScript.toLatin1();
const char* cPathToScript = ba.data();
if( MatlabEngine )
{
engEvalString( MatlabEngine, cPathToScript );
return true;
}
return false;
}
我在 engEvalString( MatlabEngine, cPathToScript );
上得到一个 CoInitialize has not been called
第一次机会异常,这似乎告诉我 Matlab COM 服务器不可用(但 Matlab 引擎仍在运行)。
虽然我将所有内容都放在同一个线程中,但它工作正常,但这不是我想要的那种设计。
我发现 Matlab 引擎文档缺少有关引擎+COM 的信息。知道如何在单独的线程中进行引擎初始化和函数调用吗?
谢谢!
根据 RobH 的回答进行编辑
我将此方法添加到我的类中(在第二个线程中实例化):
bool MY_MATLAB_FUNCTION_CALL_o::PostThreadCreationHook()
{
HRESULT hr;
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr))
{
return false;
}
return true;
}
现在当我调用 engEvalString( MatlabEngine, cPathToScript );
我得到 The application called an interface that was marshalled for a different thread
第一次机会异常 :) 我今天早上真开心! :)
那么,CoMarshalInterface()
?
最佳答案
必须从使用 COM 对象的每个线程调用 CoInitialize,而不仅仅是主线程。
自从我上次自动化 Matlab 以来已经有十年了,所以请原谅下面的生疏。您收到 CoInitialize 错误表明 engOpen 调用包装了底层 COM 调用。不幸的是,这会使您不知不觉地暴露在 COM 蠕虫病毒中。我猜你是对的,engOpen 包含对 CoInitialize 的调用,它在当前线程上初始化 COM 库。要从线程访问 COM 对象,必须始终在调用 COM 之前在该线程上调用 CoInitialize(除了一个允许的 COM 函数,我忘了是哪个。)
我的建议是现在将所有 Matlab 调用隔离到一个线程中。如果这样做,您就不必进行显式的 CoInitialize 调用,并且可以避免任何以后的多线程 COM 问题。您今天可能会通过在第二个线程上调用 CoInitialize 使您的程序正常运行,但有一天您会遇到另一个 COM 问题。
[我在 COM 上花费了大约十年的时间,它充满了熊市陷阱。您可以花几周时间阅读 Microsoft 试图用 .Net 隐藏/扼杀的技术,但最好现在就采取简单的(单线程)路径并忘记它。]
更新恐怕您的编辑使您陷入了 COM 线程模型的泥潭。 COINIT_MULTITHREADED 有效地告诉 COM 您将处理线程的所有细微差别,这几乎肯定不是您想要做的。 COM 使用多个(上次我注意到它是三个)线程模型,您传递给 CoInitializeEx 的参数声明您希望使用哪些模型。
如果以下内容略有偏差,我们深表歉意。
如果您指定 COINIT_MULTITHREADED,您需要知道您正在调用的 COM 对象是线程安全的,或者您自己进行适当的锁定(以及线程间接口(interface)和数据的编码)。
COINIT_APARTMENTTHREADED,这可能是 engOpen 使用的,根据我的经验,它是最常见的,让 COM 库为您处理多线程。例如,该库可能会创建代理和 stub 对象来调解跨线程(或进程边界,当您调用 Matlab 时会发生这种情况)的调用。
engOpen 在您的主线程上创建了一个 Matlab 代理对象。这个代理对象可以从创建它的线程调用,如果我没记错的话,可以从“公寓”中的任何其他线程调用(其中 CoInitializeEx 已使用 COINIT_APARTMENTTHREADED 调用。)您已尝试从线程调用代理在不同的线程模型中,COM 库注意到并发出了您提到的错误。
COM 在很多方面都很棒,但其复杂性令人头疼。感谢您永远不必使用分布式 COM,这真的很讨厌!
更新 2我对 COM 线程模型的古老内存是错误的。 This MSDN page指出每个公寓有一个线程,带有 COINIT_APARTMENTTHREADED。 COM 对象可以从创建它们的单元中的所有线程使用相同的接口(interface)指针进行访问。对于 COINIT_APARTMENTTHREADED,这意味着仅创建对象的线程。在 COINIT_MULTITHREADED 中,这将是多线程单元中的所有线程,但 (1) 如果您使用 engOpen,您将无法选择在哪个线程上创建 Matlab 引擎,以及 (2) 尝试调用您没有调用的 COM 对象从多线程单元写入是有风险的。顺便说一下,原始的 OLE 线程模型只允许来自主 GUI 线程的 COM 调用。
关于c++ - 使用 Matlab 引擎的多线程 C++ 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19250493/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!