gpt4 book ai didi

c# - 在 C++ (COM) Dll 导入中使用 C# 代码不太正确

转载 作者:太空宇宙 更新时间:2023-11-04 12:57:22 24 4
gpt4 key购买 nike

如标题所示,我很难从 C++ 调用 C# 代码。一些上下文:在 C# 中有一个 API 调用(在 API 的 C++ 版本中不存在),我需要将它集成到一个更大的 C++ 项目中。

我一直在阅读 this SO post , 并以 COM 方法取得了最大进展。

我的 C# dll 编译*。将生成的 dll 和 tlb 文件复制到相应的 C++ 项目目录后,我在同一 C++ 项目目录中打开一个管理命令提示符并运行:

regasm MyFirstDll.dll /codebase /tlb

(*我将其编译为类库,程序集名称:MyFirstDll,默认命名空间:MyMethods,程序集信息... -> 选中使程序集 Com-Visible,Build->Register for COM interop 也被选中。)

使用对象浏览器,我能够看到我定义的类,以及具有适当参数和签名的方法。 Screenshot of it showing up in Object Browser

我遇到的问题是方法调用(而不是类)。尽管该方法在对象浏览器中可见,但在我的代码中它未被识别为对象的方法。

类“ATL::_NoAddRefReleaseOnCComPtr”没有成员“Add”
这是我的代码:

MyFirstDll C# 项目:

using System;
using System.Runtime.InteropServices;
//

namespace MyMethods
{
// Interface declaration.
[Guid("8a0f4457-b08f-4124-bc49-18fe11cb108e")]
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface Easy_Math
{
[DispId(1)]
long Add(long i, long j);
};
}
namespace MyMethods
{
[Guid("0cb5e240-0df8-4a13-87dc-50823a395ec1")]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MyMethods.AddClass")]
public class AddClass: Easy_Math
{
public AddClass() { }
[ComVisible(true)]

public long Add(long i, long j)
{
return (i + j);
}
}
}

NateMath.h:

#include <atlcomcli.h> 
#import "MyFirstDll.tlb"

class NateMath
{
public:
NateMath(void);
~NateMath(void);
long Add(long a, long b);

private:
CComPtr<MyFirstDll::AddClass> adder;
};

NateMath.cpp:

#include "stdafx.h"
#include <atlcomcli.h>
#import "MyFirstDll.tlb"
#include "NateMath.h"

NateMath::NateMath(void)
{
CoInitialize(NULL);
adder.CoCreateInstance(__uuidof(MyFirstDll::AddClass));
}

NateMath::~NateMath(void)
{
CoUninitialize();
}
long NateMath::Add(long a, long b) {
return adder->Add(a,b);
}

问题是在“return adder->Add(a,b)”(NateMath.cpp) 中,Add(a,b) 显示为红色,类“ATL::_NoAddRefReleaseOnCComPtr”没有成员“Add”

最佳答案

这是因为您正试图在 CComPtr 中使用您的类名而不是界面。使用 COM,所有方法都在接口(interface)上定义,而不是在实现接口(interface)的类上定义。

您可以 CoCreateInstance(__uuidof(YourClass))因为目的是创建 YourClass 的实例(由 __uuidof(YourClass) 表示的 GUID 标识)。然而,YourClass在 C++ 中是一个虚拟结构,它只存在以便您可以读取 uuid -- YourClass 的定义在从 #import 生成的 C++ 中是空的,而且永远是空的。

要解决此问题,请使用 CComPtr<YourInterface> .这告诉 C++ 你想通过该接口(interface)与引用的对象进行通信。这是要记住的规则:CComPtr 的类型参数和 CComQIPtr必须始终 是 COM 接口(interface)。该 COM 接口(interface)可以是显式定义的接口(interface),也可以是由 .NET 自动生成的“类接口(interface)”。

说到类接口(interface):如果你使用过ClassInterfaceType.AutoDual而不是 None ,你可以使用 CComPtr<_YourClass> (注意前导下划线 -- _YourClass 是类接口(interface),而 YourClass 将是类。不过,我建议按照您已有的方式进行操作。

关于c# - 在 C++ (COM) Dll 导入中使用 C# 代码不太正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45948272/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com