C# 如何与C++;具有名称空间 我有一个C++函数,我想把它暴露到C语言中去消费。catch是 C++代码声明包在命名空间< /强>: namespace OhYeahNameSpace { extern "C" __declspec(dllexport) void Dummy(); }

C# 如何与C++;具有名称空间 我有一个C++函数,我想把它暴露到C语言中去消费。catch是 C++代码声明包在命名空间< /强>: namespace OhYeahNameSpace { extern "C" __declspec(dllexport) void Dummy(); },c#,c++,interop,C#,C++,Interop,我的问题是,如何定义相应的C#结构?我相信C#code必须意识到Ohyehnamespace的存在,对吗 编辑:我想很多人误解了我的观点(不,谢谢,因为我原来的示例中有一个输入错误;已修复)。我想问的是,如果存在导出函数所关注的名称空间,该如何处理。这一部分缺少一个答案,另一个说这不可能,请我总结一下,另一个现在是-1票 为什么不使用C++/CLI包装 //ohyeah.h namespace OhYeahNameSpace { public ref class MyClass {

我的问题是,如何定义相应的C#结构?我相信C#code必须意识到
Ohyehnamespace
的存在,对吗


编辑:我想很多人误解了我的观点(不,谢谢,因为我原来的示例中有一个输入错误;已修复)。我想问的是,如果存在导出函数所关注的名称空间,该如何处理。这一部分缺少一个答案,另一个说这不可能,请我总结一下,另一个现在是-1票

为什么不使用C++/CLI包装

//ohyeah.h
namespace OhYeahNameSpace
{
  public ref class MyClass
  {
     void Dummy();
  }
}

//ohyeah.cpp
#include "ohyeah.h"
namespace OhYeahNameSpace
{
void MyClass::Dummy()
{
// call the real dummy in the DLL
}

}

一种可能的解决方案是使用p/Invoke(除了前面提到的包装在C++/CLI类中的方法之外)

在C++中(我假设您的函数在一个项目中,导致一个名为unMaundCPP.DLL:

的DLL。
namespace OhYeahNameSpace
{
   extern "C" __declspec(dllexport) void Dummy(); //extern "C" to disable name mangling
}
在C#中:

C#应用程序应该能够找到UnmanagedCpp.dll(即,您可以将其复制到exe的bin中)

编辑:

这个解决方案有一些缺点需要考虑。在评论之后,我在提出我的“解决方案”时没有明确说明一些事情

  • 使用C++/CLI包装是更好的解决方案
  • 当前,VS 2010编译器(及其前身)禁用名称空间中的函数名称混乱,如果该函数是使用外部“C”导出的。然而,这被认为是一个bug,这意味着它可能在将来某个时候被修复。我不会屏住呼吸,直到他们这么做…一位评论人提供的链接中的bug在2005年和5年后被报道…此外,当前的行为更像是一个功能IMHO。如果你想正确修饰名称(还有名称空间名称)那么不应该将其声明为extern“C”。但这只是我个人的观点。所以要考虑到这一点

  • 包装为C并使用p/Invoke:

    --- OhYeahNameSpace_C.h ---
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void _declspec(dllexport) OhYeahNameSpace_Dummy();
    
    #ifdef __cplusplus
    }
    #endif
    
    --- OhYeahNameSpace_C.c ---
    #include "OhYeahNameSpace_C.h"
    #include <OhYeahNameSpace.h>
    
    void OhYeahNameSpace_Dummy()
    {
      ::OhYeahNameSpace::Dummy();
    }
    
    ——Ohyehanamespace\u C.h---
    #ifdef_uucplusplus
    外部“C”{
    #恩迪夫
    void _declspec(dllexport)OhYeahNameSpace_Dummy();
    #ifdef_uucplusplus
    }
    #恩迪夫
    ---Ohyehnamespace_C.C---
    #包括“Ohyehnamespace_C.h”
    #包括
    void Ohyehnamespace_Dummy()
    {
    ::OhYeahNameSpace::Dummy();
    }
    

    这个例子并不是100%完整,但你可以理解它的要点。

    我可以,但最重要的是,如何从C#(而不是另一个C++)调用它?这是正确的答案。p/Invoke应该只用于调用带有“C”接口的函数,这意味着
    extern“C”
    以防止名称混乱,以及对参数和返回类型的限制。@Ben,请注意,对于这个答案,
    名称空间
    根本不进入C代码(并且没有C代码),我很难相信这可能是答案。我认为如果你能演示C#如何调用C++/CLI包装器,这将有助于Graviton理解这个答案。@Graviton添加对包含C++/CLI包装器的DLL的引用。之后,你可以在C#:Ohyaheahnamespace.MyClass obj=new OhYeahNameSpa中执行此操作ce.MyClass();obj.Dummy();所以你使用它就像使用其他C#一样class@ds27680,据我所知,
    OhYeahNameSpace
    没有在C#中指定,那么C#到底怎么知道在哪里查找
    Dummy
    函数呢?这是行不通的。DLL导出表中的函数名不是
    Dummy
    或它所使用的任何简单变体P/Unjk知道如何处理。你可以查找被损坏的名字并在 DLimPult属性中使用它,但是在C++ DLL被重新编译的任何时候都会受到破坏。Ben Voigt不适用于VS 2010……用“外部”C函数名称不会被破坏(即使它在命名空间中)。我认为有人控制C++代码。KEN Bloom。是的,我想你是对的。bug报告适用于我的解决方案。所以我认为使用这个“特征”(读bug)不是一个好主意,因为bug可能在将来某个时候被修复。
    --- OhYeahNameSpace_C.h ---
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void _declspec(dllexport) OhYeahNameSpace_Dummy();
    
    #ifdef __cplusplus
    }
    #endif
    
    --- OhYeahNameSpace_C.c ---
    #include "OhYeahNameSpace_C.h"
    #include <OhYeahNameSpace.h>
    
    void OhYeahNameSpace_Dummy()
    {
      ::OhYeahNameSpace::Dummy();
    }