调用托管代码的非托管代码在开发机器上工作,而不是在部署机器上工作
Unmanaged code calling managed code works on dev machine, not on deployed machine
我正在构建一个基于VideoRendererElement项目(http://videorendererelement.codeplex.com/)的网络摄像头应用程序,它使用DirectShowLib和与非托管activex组件的互操作。我正在使用Visual Studio 2010,但我的目标是。net 3.5 (2.0 clr运行时)。
我已经能够在我的开发机器上构建和运行应用程序,没有任何问题(甚至在Visual Studio之外)。然而,当我在目标机器(Windows 7)上部署应用程序时,. NET最新,c++可重新发布最新)应用程序崩溃。我设置了一个额外的方法来将正在运行的应用程序记录到目标机器上的一个文本文件中——跟踪到一个关键的区别,非托管代码调用托管代码中的方法,只有以前定义的静态字段丢失了。这只发生在目标机器上(我将代码部署到的机器)。下面是一些代码片段和我记录的内容。令人困惑的是,这个错误只发生在目标机器上。如果您能给我指出正确的方向,我将不胜感激。
namespace MediaBridge
{
.....
public class MediaBridgeManager
{
public delegate void NewMediaGraphInfo(MediaBridgeGraphInfo GraphInfo);
private static readonly Dictionary<string, NewMediaGraphInfo> _delegateHash = new Dictionary<string, NewMediaGraphInfo>();
......
public static void AddMediaGraphInfo(MediaBridgeGraphInfo GraphInfo)
{
if (_delegateHash.ContainsKey(GraphInfo.MediaUrl))
{
NewMediaGraphInfo callback = _delegateHash[GraphInfo.MediaUrl];
_delegateHash.Remove(GraphInfo.MediaUrl);
/* Suppress all errors on the callback */
try
{
callback(GraphInfo);
}
catch {}
}
}
......
public static bool RegisterCallback(string MediaUrl, NewMediaGraphInfo Callback)
{
bool returnval = true;
MediaUrl = FormatUrl(MediaUrl);
if (!_delegateHash.ContainsKey(MediaUrl))
{
_delegateHash.Add(MediaUrl, Callback);
}
else
{
returnval = false;
}
return returnval;
}
}
}
在应用程序的。net部分首先调用RegisterCallback()并使用URL和回调函数填充_delegateHash之前。这在目标计算机上的日志文件中得到了验证。
现在是未管理的部分:
STDMETHODIMP CMediaBridgeSourceFilter::Load(LPCOLESTR lpwszFileName, const AM_MEDIA_TYPE *pmt)
{
/* Thread-saftey */
CAutoLock cAutoLockShared(&m_cSharedState);
HRESULT phr = S_OK;
/* Create the output pin for our filter */
m_pPin = new CMediaBridgeSourceFilterPin(&phr, this);
/* Create a new class to store information about us/graph in it */
MediaBridge::MediaBridgeGraphInfo ^ graphInfo = gcnew MediaBridge::MediaBridgeGraphInfo();
/* Set the media url sent */
graphInfo->MediaUrl = gcnew System::String(lpwszFileName);
/* Set the pointer to the filter graph */
graphInfo->FilterGraph = System::IntPtr(this->GetFilterGraph());
/* Store the pointer for our instance of the filter */
graphInfo->SourceFilter = System::IntPtr(this);
/* Do the callback into our managed code */
MediaBridge::MediaBridgeManager::AddMediaGraphInfo(graphInfo);
return phr;
}
根据我的日志文件MediaBridge::MediaBridgeManager::AddMediaGraphInfo()正在. net端被调用,但回调从未达到,因为_delegateHash变量现在为空。
以下是我的日志文件在我试图部署应用程序的目标机器上的内容:
RegisterCallback(): MediaUrl = dshowmediabridge://d0ffd222-d023-483b-8fc7-4b4035ce3922/ Contains Key: True Delegate Hash count: 1
InitializeDirectShow(): RegisterCallback == true, Url == DShowMediaBridge://d0ffd222-d023-483b-8fc7-4b4035ce3922
AddMediaGraphInfo(): MediaUrl = dshowmediabridge://d0ffd222-d023-483b-8fc7-4b4035ce3922/ FilterGraph: 71122304 Contains Key: False Delegate Hash count: 0
请注意,当非托管代码调用AddMediaGraphInfo()时,Delegate哈希计数(_delegateHash.Count)现在是0。
我应该做些什么来识别目标机器上的dll到com/c++, VS在我的开发机器上为我做的?
如何在目标机器上部署和运行应用程序。您是简单地复制可执行文件还是创建一个安装程序?如果您正在创建安装程序,您是否在RegSvr32中注册了AX文件?
COM组件的问题是它们必须在相关盒子上的注册表中注册。在你的盒子上,你已经注册了这个,所以你不会有问题。然而,在目标框上,它可能被注册,也可能不被注册,这取决于用户的突发奇想。如果您已经设置了安装程序,则必须"安装"AX文件,以便在注册表中注册它。否则,无论您如何部署AX文件,都无法找到AX文件。这是COM的缺点之一。
- QSqlquery prepare()和bindvalue()不工作
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 如果C++依赖于机器,那么用C++编写的软件如何在不同的计算机上工作
- OpenCl代码在一台机器上工作,但我在另一台机器中得到了CL_INVALID_KERNEL_ARGS
- OpenGL Shader 在 AMD 机器中无法正常工作
- 在win10机器上使用winsock的UDP广播不工作
- c++ OpenCV VideoCapture在不同机器上的工作方式不同
- QtSql应用程序不能在已部署的机器上工作
- 如何编译一个程序在64位机器上工作
- 调用托管代码的非托管代码在开发机器上工作,而不是在部署机器上工作
- C++程序在两台不同的机器上编译.共享库在一个上正常工作.另一方面,类方法返回NULL
- 在我自己的机器上工作,但在 SPOJ 上工作
- pthread程序导致Linux机器出现分段错误.在Cygwin64上工作良好
- 为什么clock()不能在集群机器上工作
- Boost序列化在32位和64位机器之间不工作.任何其他序列化/压缩库