使用 COM 接口 C# 从 c++ 访问会产生错误

Posted

技术标签:

【中文标题】使用 COM 接口 C# 从 c++ 访问会产生错误【英文标题】:Using COM interfaces C# to access from c++ produces error 【发布时间】:2013-03-09 15:52:49 【问题描述】:

我有一个 c++ 项目,它将调用一个 C# 函数,然后,c# 将调用一个 c++ 函数(两者都有返回值)。我卡在***上有人给我的COM接口上(我对c++或c#没有太多经验,只有java),但由于某种原因,当我尝试编译C++代码时它给了我一个错误,致命错误C1196 : 'FaceTrackingBasics-WPF' : 在类型库 c:\FaceTrackingBasics-WPF/bin/x86/Debug/FaceTrackingBasics-WPF.tlb 中找到的标识符不是有效的 C++ 标识符。

你能发现一些错误吗?也许我不应该在一个文件中有两个类?顺便说一句,c# 代码与一个窗口相关联,我不知道它是否会导致问题。 谢谢

C#代码

    // --------------------------------------------------------------------------------                ------------------------------------
    // <copyright file="FaceTrackingViewer.xaml.cs" company="Microsoft">
    //     Copyright (c) Microsoft Corporation.  All rights reserved.
    // </copyright>
    // --------------------------------------------------------------------------------        ------------------------------------

    namespace FaceTrackingBasics
    
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Kinect;
using Microsoft.Kinect.Toolkit.FaceTracking;

using System.Globalization;

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


using Point = System.Windows.Point;

/// <summary>
/// Class that uses the Face Tracking SDK to display a face mask for
/// tracked skeletons
/// </summary>
public partial class FaceTrackingViewer : UserControl, IDisposable

    public static readonly DependencyProperty KinectProperty = DependencyProperty.Register(
        "Kinect", 
        typeof(KinectSensor), 
        typeof(FaceTrackingViewer), 
        new PropertyMetadata(
            null, (o, args) => ((FaceTrackingViewer)o).OnSensorChanged((KinectSensor)args.OldValue, (KinectSensor)args.NewValue)));

    private const uint MaxMissedFrames = 100;



    private Boolean drawFlat = false;

    public FaceTrackingViewer()
    
        this.InitializeComponent();
    

    ~FaceTrackingViewer()
    
        this.Dispose(false);
    

    public KinectSensor Kinect
    
        get
        
            return (KinectSensor)this.GetValue(KinectProperty);
        

        set
        
            this.SetValue(KinectProperty, value);
        
    

    public void Dispose()
    
        this.Dispose(true);
        GC.SuppressFinalize(this);
    


    //i deleted the rest of the code, i dont think its relevant
    


//***********************//

[ComVisible(true)]
[Guid("2EF06BCB-A25B-41AD-B233-33A956DBEB69")]
public struct Ponto

    public double x;
    public double y;

    public Ponto(double x, double y)
    
        this.x = x;
        this.y = y;
    


[ComVisible(true)]
[Guid("EB9258F5-DCFB-4F91-8342-5A05EB17557D")]
public interface IManagedClass

    Ponto[] Foo();


[ComVisible(true)]
[Guid("11B23AD7-F79E-45D7-BC87-89F0DBC8B83F")]
[ClassInterface(ClassInterfaceType.None)]
public class ManagedClass : IManagedClass

    private List<Ponto> points;

    public ManagedClass()
    
        points = new List<Ponto>();
        points.Add(new Ponto(1.0, 1.0));
        points.Add(new Ponto(2.0, 2.0));
        points.Add(new Ponto(3.0, 3.0));
    

    public Ponto[] Foo()
    
        return points.ToArray();
    

c++代码

   #include "stdafx.h"

   #import        "C:/Users/Pedro/Dropbox/0000000TESE/000_visual_studio/0FaceTMS/FaceTrackingBasics-              WPF/bin/x86/Debug/FaceTrackingBasics-WPF.tlb"
   #include <iostream>

   using namespace FaceTrackingBasics;
   using namespace std;

   int main()
   
::CoInitialize(NULL);


    IManagedClassPtr pManagedClass(__uuidof(ManagedClass));

    SAFEARRAY* psa = pManagedClass->Foo();
    Ponto* pPoints = (Ponto*)psa->pvData;

    for (int i = 0; i < 3; ++i)
        cout << pPoints[i].x << " " << pPoints[i].y << endl;


::CoUninitialize();
 

【问题讨论】:

#import路径中有14个空格,在FaceTrackingBasics-之后,这些空格应该在那里吗,它们在你的原始代码中吗? 你有没有修改你的 assambly 像 [ComVisible(true)] ? scott,它是一个复制粘贴错误,在我的代码中它全部放在一起,没有空格。 thanatos,我不明白你的意思,但我的代码中有那个“指令” 【参考方案1】:
'FaceTrackingBasics-WPF' : ... is not a valid C++ identifier

不是,C++ 标识符不能包含破折号“-”。就像 C# 顺便说一句。此名称来自您的项目名称。其中设置类型库名称。其中设置了#import 指令创建的命名空间的名称。

除了简单地重命名您的项目之外,还有几种可能的解决方法。你可以apply attributes 到#import 指令。像“auto-rename”、“no-namespace”和“rename-namespace”:

   #import "FaceTrackingBasics-WPF.tlb" rename_namespace("managed")
   using namespace managed;

【讨论】:

谢谢!我按照你说的做了,它现在可以构建解决方案,但 Visual Studio 仍然在“使用管理的命名空间”和我所有的 C++ 代码主类上给我红色。有什么想法吗? 我错过了 #include 。解决了,谢谢大家的帮助!

以上是关于使用 COM 接口 C# 从 c++ 访问会产生错误的主要内容,如果未能解决你的问题,请参考以下文章

从 C# 到 C++ 触发 COM 事件的正确方法是啥

如何将 C# 客户端 RPC 写入远程本机 C++ 服务器?

是否可以对 C# COM 接口实现进行故障排除?

如何使用原生 C++ 的 COM 实现 C# 的接口?

如何使用 C++ 封装的 COM 接口部署 C# 库?

调用 COM 服务器,C++ CoCreateInstance 抛出“不支持此类接口”,C# 正常工作