从c++调用c#,“& "”的困难在c#命名空间中

本文关键字:命名空间 quot 调用 c++ | 更新日期: 2023-09-27 18:12:30

首先,我承认我对这段代码有点过分了——当我把它应用到现实世界中时,我的整洁的示例代码无法正常工作。

我有一个名为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也没用。

我难住了。

从c++调用c#,“& "”的困难在c#命名空间中

c++不使用.操作符来分隔命名空间;它使用::。您将使用CPierce::CSharpBridge而不是CPierce.CSharpBridge。不幸的是,这似乎对您没有帮助,因为您不知道TLB实际生成的名称空间是什么。

一个简单的解决方案是根本不使用名称空间,并且不使用它们进行导入:

#import "CPierce.CSharpCall.tlb" named_guids no_namespace

这似乎是c#/Visual Studio方面的一个问题。我就不提这个问题了,换个合适的问题。谢谢你帮我缩小范围