c++应用程序找不到com dll,因为编译器使用不正确的guid生成.tlh文件
c++ application cannot find com dll because compiler generating .tlh file with incorrect guids
我有一个在c++项目中使用的com dll。我没有注册dll,但它在同一个解决方案中。我的应用程序不断中断,我发现它在这里中断
hr = CoCreateInstance(rclsid, pOuter, dwClsContext, __uuidof(IUnknown), reinterpret_cast<void**>(&pIUnknown));
因为我没有具有该guid(rclsid)的com类。我做了更多的挖掘,发现它从临时目录中的.tlh文件中获取guid,但guid与我的代码不同。
.tlh文件
struct __declspec(uuid("b10a18c8-7109-3f48-94d9-e48b526fc928"))
DocMapEntry;
// [ default ] interface _DocMapEntry
// interface _Object
// interface IDocMapEntry
c#代码(可视dll)
[ComVisible(true)]
[Guid("E98676B9-1965-4248-A9B6-74EC5EE5385A")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IDocMapEntry
{
int Offset { get; set; }
int PageOffset { get; set; }
int PageNumber { get; set; }
}
我尝试将值更改为正确的值,但它不断更改,visual studio要求我重新加载。
当我使用com资源管理器查看该类时,我会得到一个不同的clsid,当我尝试注销它时,它成功地完成了,但项目仍然存在,文件位置是mscoree。
我的c++应用程序使用.tlh文件中的guid,但找不到该文件。
public class DocMapEntry : IDocMapEntry
{
...
}
我的问题是。
我需要注册我的com dll才能工作吗?如何设置类的guid?为什么它会创建一个guid错误的临时.tlh文件?(可选)为什么我不能更改这个文件?(可选)
谢谢。
public interface IDocMapEntry
COM强烈区分CLSID和IID。接口标识符IID标识COM对象实现的接口。我们可以看到,您使用[Guid]属性指定了它。您将它作为CoCreateInstance()的第四个参数传递,现在您将在其中传递IUnknown的IID。
您需要的是CLSID,类标识符。我们在您的代码片段中看不到它,它是用于类实现您的IDocMapEntry的代码片段。它有可能被命名为DocMapEntry。还有你没有给它一个[Guid]的额外几率,所以CLR会自动为你生成一个。请注意,当您修改类时,它将更改,这可能是CoCreateObject()失败的原因之一。
忘记用Regasm.exe/codebase注册.NET程序集是另一个原因,您在问题中也提到了同样多的原因。这是必需的,否则COM将无法找到DLL并导致调用失败,错误代码为0x80040154,"类未注册"。把它放在同一个解决方案中是不够的,COM搜索规则与.NET.使用的规则完全不同
还要注意,您正在公开类的内部,通过在类上应用[ClassInterface(ClassInterfaceType.None)]特性来避免这种情况。
不需要注册COM DLL,但需要注册一个负责创建COM对象的对象。在COM子系统初始化后(通过调用CoInitialize
或CoInitializeEx
),在应用程序中调用CoRegisterClassObject
。
IClassFactory *factory = new ObjectFactory();
// Register the factory responsible for creating our COM objects
DWORD classToken;
HRESULT hr = CoRegisterClassObject(
Object_CLSIID,
factory,
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&classToken);
// Now we can create the objects
Object *obj = nullptr;
hr = CoCreateInstance(
Object_CLSIID,
nullptr,
CLSCTX_LOCAL_SERVER,
Object_IID,
reinterpret_cast<void**>(&obj));
不确定它为什么要创建一个临时.tlh
,但我怀疑这是您的构建设置中的内容——可能是在构建步骤中。
您的COM对象在C#dll中吗?如果是,您以前在系统中运行过regasm吗?系统可能已经注册了COM dll。
Guid("E98676B9-1965-4248-A9B6-74EE5385A"):这是您的接口Guid,而不是组件Guid。
您应该在实现类中为COM对象声明一个GUID,该GUID应该是b10a18c8-7109-3f48-94d9-e48b526fc928。
为什么它会创建一个guid错误的临时.tlh文件?
您确定没有使用#import关键字导入COM dll吗。
- 使用2个键的cpp-stl::优先级队列排序不正确
- 正弦级数方程计算不正确
- 我试图制作一个程序,要求用户输入问题和答案,但程序循环不正确
- 密码登录程序将永远循环并显示不正确的结果
- 在C++中返回不正确的楼层函数值
- 形状对象的旋转和缩放不正确C++
- C++ 读取文件读取文件不正确
- 关于类的 Python 文档 - 对C++的引用不正确
- 特征 LLT 模块给出不正确的结果?
- glibcxx STL 在实现 std::valarray::sum() 时是否不正确?
- 如果语句逻辑不正确
- 来自逆 vp 矩阵和相机位置的光线方向不正确
- 不正确的操作数类型 MSVC
- 数组填充了不正确的值
- 我是否不正确地集中了这些字符数组?
- 为什么除非我使用 cout,否则我的值不正确?
- 计算幂级数的数学结果不正确
- 为什么 sizeof 在 C++ 中给出不正确的字节数?
- atoi() 在应用于大型命令行参数时会产生不正确的值
- c++应用程序找不到com dll,因为编译器使用不正确的guid生成.tlh文件