如标题所示,我很难从 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/