繁体   English   中英

如何从 c++ 代码访问 c# 库的 static 成员?

[英]How do I access static members of a c# library from c++ code?

我得到了一个用 C# 编写的库,我需要在 C++ 项目中使用它。 C# 库已导出到 a.tlb 类型库,我可以使用 #import 指令将其成功导入到我的 C++ 项目中。

对 COM 完全不熟悉,我一生都无法弄清楚如何在任何类上使用 static 成员函数。 这是我在 C# 中访问它的方法:

void Function()
{
    StaticClass.StaticMethod();
}

然后进入 C++ 端,.tlh 文件中生成的是:

struct __declspec(uuid("some big long thing")) 
/* dual interface */_StaticClass;
//long while later
_COM_SMARTPTR_TYPEDEF(_StaticClass, __uuidof(_StaticClass));

因此,我试图弄清楚如何使用 static class 并且对谷歌没有任何运气。 在我可以访问的任何其他项目中,唯一的例子给了我类似的东西:

_StaticClassPtr s = _StaticClassPtr(__uuidof(_StaticClass));

但无论如何,我的示例不适用于 static class。

基本上,我什至无处可开始真正开始。 这将失败,并出现“<executable> 中的未处理异常:Microsoft C++ 异常:memory 位置 <location> 处的 _com_error”


编辑:由于@dxiv 通知我 static 方法不能与 COM 互操作一起使用,还有另一个标记为“过时”的选项不使用 ZA81259CEF8E959C624DF1D456E5D32

IInstanceClassPtr p = _IInstanceClassPtr(__uuidof(_InstanceClass));

抛出相同的异常,“_com_error at memory 位置”

阅读您的问题,您想通过 COM 互操作来使用 C#。 我所做的是这样的。 Starting from the assumption that COM is the acronym of Component Object Model and to use it you need an instantiable, local or remote, object. 下面的示例创建 CLR object 的“进程内”实例。

创建一个暴露给 COM 的接口:

namespace MyNamespace
{
    /// <summary>
    /// Provides an entry point for COM clients.
    /// </summary>
    [ComVisible(true)]
    [Guid("A9E6D7FE-34FD-4A6B-9EB2-DC91F4AE567B")]
    public interface IMyAccessor
    {
         void ExecuteStaticMethod();
         // add anything else like methods, property,
    }
}

然后在 C# class 中实现接口:

namespace MyNamespace
{
    /// <summary>
    /// The implementation of IMyAccessor.
    /// </summary>
    [ComVisible(true)]
    [Guid("C65A7F81-641C-4F17-B34A-DEB88B4158E8")]
    [ProgId("MyCompany.MyAccessor")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(IMyAccessor))]
    public sealed class MyAccessor: IMyAccessor
    {
        public void ExecuteStaticMethod() { StaticClass.StaticMethod(); }
    }
}

export the TLB and import it in C++ project (MyAccessor is only a name I used here) in the header file of your C++ class using the following clause:

#import "MyAccessor.tlb"

在 class header 中添加如下一行:

MyNamespace::IMyAccessorPtr m_IMyAccessor;

并在 class 实现中使用以下内容:

        HRESULT hr = m_IMyAccessor.CreateInstance(__uuidof(MyNamespace::MyAccessor));
        if (FAILED(hr))
        {
            // do something if failed
        }

        m_IMyAccessor->ExecuteStaticMethod(); // this will execute your static method in C#

注意:导出 TLB 时使用正确的开关。 在 x64 环境 (/win64) 中必须使用正确的指针大小:通常 tlbexp 返回可在 32 位环境中使用的指针。 如果您想使用更复杂的方法扩展 class,这一点很重要。

注意 2 :如果CreateInstance返回的 HRESULT 类似于“类未注册”,请记住使用 REGTLIB 执行 TLB 的注册。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM