这是.tlh文件是否正确,如果没有,那么如何生成正确的文件? [英] Is this .tlh file correct, and if not, then how do I generate the correct one?

查看:503
本文介绍了这是.tlh文件是否正确,如果没有,那么如何生成正确的文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从非托管C ++代码调用.NET 4.0 dll。



我按照 Atul Mani的这个代码项目文章



NET dll,并按照所有步骤,包括注册它与regasm。



接下来,我创建了一个非托管C ++项目,并添加这一行在开始。 cpp文件:

  #importD:\PathToMyCSharpProject\bin\Debug\com.DeviceServices.tlbrename (EOF,adoEOF)no_namespace named_guids raw_interfaces_only 



当我构建C ++项目时, tlh文件在D:\ MyCPlusPlusProject \Debug中创建。



接下来,我添加了CodeProject文章建议的代码,它试图创建一个指向一个对象的指针从C#库。

  CoInitialize(NULL); //初始化所有COM组件

//< namespace> ::< InterfaceName>
MyCSharpNamespace :: IMyCSharpInterfacePtr pMyCSharpInterfacePtr;



MyCSharpNamespace是我在C#项目中使用的命名空间。



当我构建C ++项目时,现在得到一个编译错误:


错误2错误C2653: MyCSharpNamespace':不是类或命名空间名称


还有其他错误,因为它不能识别IMyCSharpInterfactPtr。



所以,我查看了.tlh文件,内容如下:

  //由Microsoft(R)C / C ++编译器版本10.00.40219.01(6478e0c7)创建。 
//
// MyCPlusPlusProjectPath\debug\com.deviceservices.tlh
//
// C ++源代码相当于Win32类型库MyCSharpProjectPath\bin\Debug\\ \\ com.DeviceServices.tlb
//编译器生成的文件创建于05/27/14在11:52:16 - 不要编辑!

#pragma once
#pragma pack(push,8)

#include< comdef.h>

//
//转发引用和typedefs
//

struct __declspec(uuid(961b3c24-98f2-400e-8bea-ab357a18d851 ))
/ * LIBID * / __MyCSharpProject;

//
//命名的GUID常量初始化
//

externCconst GUID __declspec(selectany)LIBID_MyCSharpProject =
{0x961b3c24,0x98f2,0x400e,{0x8b,0xea,0xab,0x35,0x7a,0x18,0xd8,0x51}};

#pragma pack(pop)

找出.tlh文件中应包含的内容,并在msdn中找到 #import页面。



它表示.tlh文件的内容应该包含智能指针声明(即IMyCSharpProjectInterfacePtr)和typeinfo声明,它们不存在于我的.tlh文件。



MyCSharpProject声明一个公共接口,包括一个生成的GUID,正确构建,并且我从文章中遵循的所有步骤似乎都是成功的。

所以,我的问题是,有人可以建议为什么这些定义不存在于我的.tlh文件,应该在那里?

解决方案

.tlh文件不能错,它是从COM服务器的类型库自动生成的。一个明显的缺陷是它是空的,你根本看不到任何声明。



问题是与Codeproject.com文章,par为课程这样的项目是,它缺少一个必要的步骤,不解释什么是真正在发生,经常使用非常糟糕的做法。为了能够从COM客户端使用.NET类型,您必须明确地使它对COM客户端可见。将此属性添加到您要导出的每个类型:

  [ComVisible(true)] 



应用于接口和类。



使用[Guid ]属性,像作者提出的,是非常危险的。在开发库时,可以将它保留在原位,它有助于避免注册表污染,并允许您跳过Regasm步骤(不总是),但在发运库之前再次删除它是非常重要的。 COM中一个坚硬的规则是,对接口的修改需要一个新的guid,一个重要的DLL地狱对策。



在您开发时,最好避免在GAC中注册程序集,因为这样可以自动生成一个新的程序集。它导致了太多的事故,在GAC中留下一个过时的大会副本。在Regasm命令中使用 / codebase 选项,因此不需要。您可以忽略您收到的警告。


I am trying to call a .NET 4.0 dll from unmanaged C++ code.

I followed the instructions in this Code Project article by Atul Mani.

I built the .NET dll, and followed all the steps up to and including registering it with regasm.

Next, I created an unmanaged C++ project and added this line at the start of the .cpp file:

#import "D:\PathToMyCSharpProject\bin\Debug\com.DeviceServices.tlb" rename ("EOF","adoEOF") no_namespace named_guids raw_interfaces_only

When I built the C++ project, a .tlh file was created in D:\MyCPlusPlusProject\Debug.

Next, I added the code suggested by the CodeProject article, which tries to create a pointer to an object from the C# library.

CoInitialize(NULL);   //Initialize all COM Components

// <namespace>::<InterfaceName>
MyCSharpNamespace::IMyCSharpInterfacePtr pMyCSharpInterfacePtr;

"MyCSharpNamespace" is the namespace that I used in the C# project.

When I build the C++ project, I now get a compile error:

Error 2 error C2653: 'MyCSharpNamespace' : is not a class or namespace name

Also other errors because it doesn't recognise IMyCSharpInterfactPtr.

So, I looked into the .tlh file, and the contents are as follows:

// Created by Microsoft (R) C/C++ Compiler Version 10.00.40219.01 (6478e0c7).
//
// MyCPlusPlusProjectPath\debug\com.deviceservices.tlh
//
// C++ source equivalent of Win32 type library MyCSharpProjectPath\bin\Debug\com.DeviceServices.tlb
// compiler-generated file created 05/27/14 at 11:52:16 - DO NOT EDIT!

#pragma once
#pragma pack(push, 8)

#include <comdef.h>

//
// Forward references and typedefs
//

struct __declspec(uuid("961b3c24-98f2-400e-8bea-ab357a18d851"))
/* LIBID */ __MyCSharpProject;

//
// Named GUID constants initializations
//

extern "C" const GUID __declspec(selectany) LIBID_MyCSharpProject =
    {0x961b3c24,0x98f2,0x400e,{0x8b,0xea,0xab,0x35,0x7a,0x18,0xd8,0x51}};

#pragma pack(pop)

I searched on the internet to find out what should be in the .tlh file, and found the #import page at msdn.

It says that the contents of the .tlh file should include smart pointer declarations (i.e. IMyCSharpProjectInterfacePtr) and typeinfo declarations, that are not present in my .tlh file.

MyCSharpProject declares a public interface, includes a generated GUID, builds correctly, and all the steps that I followed from the article appeared to be successful.

So, my question is, can someone suggest why these definitions aren't present in my .tlh file that should be there?

解决方案

A .tlh file cannot be wrong, it is auto-generated from the type library of your COM server. An obvious flaw is that it is rather empty, you don't see any declarations at all.

The problem is with that Codeproject.com article, par for the course in such projects is that it is missing an essential step, doesn't explain what is really going on and often uses very bad practices. In order for a .NET type to be usable from a COM client, you have to be explicit about making it visible to COM clients. Add this attribute to every type that you want to export:

  [ComVisible(true)]

Apply it to both the interface and the class.

Using the [Guid] attribute, like the author proposes, is very dangerous. It is okay to leave it in place while you are developing the library, it helps avoid registry pollution and lets you skip the Regasm step (not always), but it is pretty important to remove it again before you ship the library. A rock-hard rule in COM is that a modification to an interface requires a new guid, an essential DLL Hell counter-measure. You automatically get a new one when you leave it up to the CLR to auto-generate one.

Registering the assembly in the GAC is also best avoided while you are developing, it causes too many accidents with leaving a stale copy of the assembly in the GAC. Use the /codebase option in the Regasm command so this is not needed. You can ignore the warning you get.

这篇关于这是.tlh文件是否正确,如果没有,那么如何生成正确的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆