【发布时间】:2011-10-27 15:59:01
【问题描述】:
首先,我承认我对这个有点吹毛求疵——我漂亮干净的示例代码在我将它嵌入现实世界时不起作用。话说……
我有一个名为 CPierce.CSharpCall.dll 的 DLL,其中包含类似以下 C# 的内容:
namespace CPierce.CSharpBridge
{
[System.Runtime.InteropServices.Guid("3D08DF02-EFBA-4A65-AD84-B08ADEADBEEF")]
public interface ICSide
{
// interface definition omitted...
}
[System.Runtime.InteropServices.Guid("CBC04D81-398B-4B03-A3D1-C6D5DEADBEEF")]
public partial class CSide : ICSide
{
// class definition omitted...
}
}
这是用regasm /tlb等注册的。然后,我的C++代码看起来像这样:
#import "CPierce.CSharpCall.tlb" named_guids
// Contains syntax errors!
int myfunc()
{
HRESULT hRes = S_OK;
CoInitialize(NULL);
CPierce.CSharpBridge::ICSide *pManagedInterface = NULL;
hRes = CoCreateInstance(
CPierce.CSharpBridge::CLSID_Class1,
NULL, CLSCTX_INPROC_SERVER,
CPierce.CSharpBridge::ICSide,
reinterpret_cast<void**> (&pManagedInterface));
// Calls to the interface omitted....
CoUninitialize();
return 0;
}
当然,问题在于 CPierce.CSharpBridge 的语法错误。我知道在 C++ 中,如果我想拥有与 C# 代码类似的命名空间,我可以说:
namespace CPierce
{
namespace CSharpBridge
{
// definitions go here
}
}
但我认为这不是我要在这里寻找的,因为我只需要引用另一个命名空间中的两个常量,而无需将整个方法放在该命名空间中。
什么是我需要完成对CoCreateInstance 的调用的C++ 语法?
更新:在更深入(更深入)的检查中,我发现我由 regasm 创建的 .tlb 文件几乎是空的。当我将所有源代码连接到一个 .cs 文件并编译时:
csc /debug /t:library BigFile.cs
regasm BigFile.dll /tlb:BigFile.tlb
我得到了一个很大(而且很有用)的 tlb 文件。
当我从 Visual Studio 编译整个项目时,我得到了一个 .DLL 文件,但 regasm 并没有对它做任何事情,而是生成了一个最小的 .tlb 文件。 (ildasm 显示两个 DLL 之间几乎没有区别)
如果我在 Visual Studio 中编译 BigFile.cs,我会得到一个同样无用的 DLL。
我被难住了。
【问题讨论】:
-
你试过用
::代替.吗? -
是的。不过有些奇怪...如果我在对象浏览器中单击 .tlb,则会将其列为 CPierce_CSharpBridge。现在,CPierce_CSharpBridge::ICSide 返回为“ICSide 不是 PR1_CSharpBridge 的成员”。没有解决,但无论如何都不同。
-
如果您没有有嵌套的命名空间,它会起作用吗?
-
我的问题可能更深一些,.tlb 文件中几乎没有任何内容——我不确定我的类型/接口是否已完全注册。 regasm 没有给出错误,但我没有从中得到有用的 .tlb 。我有一个默认构造函数……是时候仔细看看 regasm 了。
-
对我来说“。”在使用 regasm 生成 tlb 时被“_”替换。只需使用 Visual Studio 打开 tlb 文件即可显示问题。