簡體   English   中英

在C ++(COM)Dll導入中使用C#代碼無法正常工作

[英]Using C# code in C++ (COM) Dll import not working quite right

顧名思義,我很難從C ++調用C#代碼。 有一點上下文:C#中有一個API調用(在C ++版本的API中不存在),我需要將其集成到更大的C ++項目中。

我一直在閱讀這篇SO文章 ,並通過COM方法取得了最大進展。

我的C#dll會編譯*。 將生成的dll和tlb文件復制到適當的C ++項目目錄后,我在同一C ++項目目錄中打開一個admin cmd提示符並運行:

regasm MyFirstDll.dll /codebase /tlb

(*我將其編譯為類庫,程序集名稱:MyFirstDll,默認名稱空間:MyMethods,程序集信息...->已選中使程序集可查看,還檢查了Build-> Register for COM interop。)

使用對象瀏覽器,我可以看到我定義的類,以及具有適當的args和簽名的方法。 屏幕快照顯示在對象瀏覽器中

我遇到的問題是方法調用(而不是類)。 即使該方法在對象瀏覽器中可見,但在我的代碼中,該方法仍未被識別為對象的方法。

類“ ATL :: __ NoAddRefReleaseOnCComPtr”沒有成員“添加”
這是我的代碼:

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”,沒有成員“添加”

這是因為您試圖在CComPtr而不是在接口中使用您的類名。 使用COM,所有方法都在接口上定義,而不是在實現接口的類上定義。

您可以使用CoCreateInstance(__uuidof(YourClass))因為目的是創建YourClass的實例(由__uuidof(YourClass)表示的GUID標識)。 但是,C ++中的YourClass是僅存在的虛擬結構,以便您可以讀取uuid -從#import生成的C ++中的YourClass的定義為空,並且始終為空。

要解決此問題,請使用CComPtr<YourInterface> 這告訴C ++您想通過該接口與引用的對象進行通信。 這是要記住的規則: CComPtrCComQIPtr的類型參數必須始終為COM接口。 該COM接口可以是顯式定義的接口,也可以是.NET自動生成的“類接口”。

說到類接口:如果使用ClassInterfaceType.AutoDual而不是None ,則可以使用CComPtr<_YourClass> (請注意,下划線是_YourClass是類接口,而YourClass是類。我建議這樣做但是,您已經擁有的方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM