Обращение к классу C++ из проекта на C#

Тема в разделе ".NET", создана пользователем IgMuSh, 25 мар 2008.

  1. IgMuSh

    IgMuSh Гость

    Репутация:
    0
    Могу ли я в одном Solution из проекта на C# (основной модуль с оконным интерфейсом) обратиться к классу описанному в дркгом проекте (на C++).
    Если да, то как? Я загрузил оба проекта в Solution, сделал reference в первом проекте на второй, пытаюсь создать объект некоего класса, описанного во втором, не ругается.

    [codebox]private void frmMain_Load(object sender, EventArgs e)
    {
    // loading Russian syntax
    CCOMSyntaxHolder SyntaxHolder=new CCOMSyntaxHolder() ;


    if (!SyntaxHolder.LoadSyntax(morphRussian)) { };
    //return -1;

    // processing one Russian sentence (from Graphematics to Syntax)
    if (!SyntaxHolder.GetSentencesFromSynAn("мама мыла раму", FALSE, FALSE, FALSE)) { };
    //return -1;
    }[/codebox]


    Но когда дальше идёт вызов метода этого класса он пишет:
    Error 1 'COMSyntaxHolderNamespace.CCOMSyntaxHolder' does not contain a definition for 'LoadSyntax' C:\Documents and Settings\***\Мои документы\Visual Studio 2005\Projects\WindowsApplication4\WindowsApplication4\frmMain.cs

    При этом он почему-то считает, что я обращаюсь к некой структуре с тем же именем что и мой объект, но пустой и считанной откуда то из временного файла(с пометкой from metadata).

    Код (Text):
    using System;
    using System.Runtime.CompilerServices;

    namespace COMSyntaxHolderNamespace
    {
    [CLSCompliant(false)]
    [NativeCppClass]
    public struct CCOMSyntaxHolder
    {
    }
    }
    Что я делаю не так?
     
  2. Pasha

    Pasha Гость

    Репутация:
    0
    IgMuSh
    SyntaxHolder.LoadSyntax объявлен как public? Покажи объявление CCOMSyntaxHolder. И используй тэги кода.
     
  3. IgMuSh

    IgMuSh Гость

    Репутация:
    0
    Вот это у меня в COMSyntaxHolder.h (этот файл во втором проекте):
    [codebox]
    #ifndef COMSyntaxHolder
    #define COMSyntaxHolder

    #include "utilit.h"
    #include <comdef.h>
    #include <atlbase.h>
    #import "Lemmatizer.tlb"
    #import "MAPost.tlb"
    #import "Agramtab.tlb"
    #import "Graphan.tlb"
    #import "Synan.tlb"


    #pragma once

    using namespace System;

    namespace COMSyntaxHolderNamespace {
    public class CCOMSyntaxHolder
    {
    public:
    MorphLanguageEnum m_CurrentLanguage;

    GRAPHANLib::IGraphmatFilePtr m_piGraphan;
    LEMMATIZERLib::ILemmatizerPtr m_piLemmatizer;
    AGRAMTABLib::IGramTabPtr m_pGramTab;
    MAPOSTLib::IMAPostPtr m_piMAPost;
    SYNANLib::ISentencesCollectionPtr m_piSentCollection;
    LEMMATIZERLib::IPLMLineCollectionPtr m_piAfterMorphPlmLines;
    LEMMATIZERLib::IPLMLineCollectionPtr m_piBeforeSyntaxPlmLines;

    CCOMSyntaxHolder();
    ~CCOMSyntaxHolder();
    BOOL LoadSyntax(MorphLanguageEnum langua);

    void DeleteProcessors();
    BOOL LoadSyntaxModule(MorphLanguageEnum langua);

    BOOL BuildBeforeSyntax(string str, BOOL bFile, BOOL bWriteIntermFiles, BOOL bSaveIntermResults);
    BOOL BuildSyntax(BOOL bSaveIntermResults);
    BOOL GetSentencesFromSynAn(string str, BOOL bFile, BOOL bWriteIntermFiles, BOOL bSaveIntermResults);



    };
    extern string GetClauseTypeDescr(MorphLanguageEnum Language, const SYNANLib::IClausePtr& piClause, int ClauseRootNo);
    #endif
    }[/codebox]
     
  4. Electro

    Electro Гость

    Репутация:
    0
    Встречный вопрос: а загрузить сборку из др. решения не проще?
     
  5. Pasha

    Pasha Гость

    Репутация:
    0
    IgMuSh
    Объяви класс как public ref class CCOMSyntaxHolder.
     
  6. IgMuSh

    IgMuSh Гость

    Репутация:
    0
    Pasha
    Спасибо!
    Класс действительно стал доступен, но почему-то не все методы(?!)

    Вот этот участок даёт ошибку:

    [codebox]using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using COMSyntaxHolderNamespace;
    namespace TestSynAn
    {
    public partial class frmMain : Form
    {
    public frmMain()
    {
    InitializeComponent();
    }

    private void frmMain_Load(object sender, EventArgs e)
    {
    // loading Russian syntax
    CCOMSyntaxHolder SyntaxHolder=new CCOMSyntaxHolder();


    if (!SyntaxHolder.LoadSyntax(morphRussian)) { };
    //return -1;

    // processing one Russian sentence (from Graphematics to Syntax)
    if (!SyntaxHolder.GetSentencesFromSynAn("мама мыла раму", FALSE, FALSE, FALSE)) { };
    //return -1;
    }
    }
    }[/codebox]


    Вызов LoadSyntax проходит, а на вызов GetSentencesFromSynAn ругается вот так:

    [codebox]Error 2 The name 'FALSE' does not exist in the current context C:\Documents and Settings\****\Мои документы\Visual Studio 2005\Projects\WindowsApplication4\WindowsApplication4\frmMain.cs 28
    Error 3 The name 'FALSE' does not exist in the current context C:\Documents and Settings\****\Мои документы\Visual Studio 2005\Projects\WindowsApplication4\WindowsApplication4\frmMain.cs 28
    Error 4 The name 'FALSE' does not exist in the current context C:\Documents and Settings\****\Мои документы\Visual Studio 2005\Projects\WindowsApplication4\WindowsApplication4\frmMain.cs 28
    Error 1 The name 'morphRussian' does not exist in the current context C:\Documents and Settings\****\Мои документы\Visual Studio 2005\Projects\WindowsApplication4\WindowsApplication4\frmMain.cs 24[/codebox]


    Причём опять если спросить у VS оределение класса CCOMSyntaxHolder, то он показывает файл "CCOMSyntaxHolder [from metadata]":

    [codebox]using System;

    namespace COMSyntaxHolderNamespace
    {
    public class CCOMSyntaxHolder : IDisposable
    {
    public MorphLanguageEnum m_CurrentLanguage;

    public CCOMSyntaxHolder();

    public int BuildSyntax(int bSaveIntermResults);
    public void DeleteProcessors();
    public override sealed void Dispose();
    protected virtual void Dispose(bool __p1);
    public int LoadSyntax(MorphLanguageEnum langua);
    public int LoadSyntaxModule(MorphLanguageEnum langua);
    }
    }[/codebox]


    На самом же деле класс описан вот так:

    "COMSyntaxHolder.h"
    [codebox]#ifndef COMSyntaxHolder
    #define COMSyntaxHolder

    #include "utilit.h"
    #include <comdef.h>
    #include <atlbase.h>
    #import "Lemmatizer.tlb"
    #import "MAPost.tlb"
    #import "Agramtab.tlb"
    #import "Graphan.tlb"
    #import "Synan.tlb"


    #pragma once

    using namespace System;

    namespace COMSyntaxHolderNamespace {
    public ref class CCOMSyntaxHolder
    {
    public:
    MorphLanguageEnum m_CurrentLanguage;

    GRAPHANLib::IGraphmatFilePtr* m_piGraphan;
    LEMMATIZERLib::ILemmatizerPtr* m_piLemmatizer;
    AGRAMTABLib::IGramTabPtr* m_pGramTab;
    MAPOSTLib::IMAPostPtr* m_piMAPost;
    SYNANLib::ISentencesCollectionPtr* m_piSentCollection;
    LEMMATIZERLib::IPLMLineCollectionPtr* m_piAfterMorphPlmLines;
    LEMMATIZERLib::IPLMLineCollectionPtr* m_piBeforeSyntaxPlmLines;

    CCOMSyntaxHolder();
    ~CCOMSyntaxHolder();

    BOOL LoadSyntax(MorphLanguageEnum langua);
    BOOL BuildBeforeSyntax(string str, BOOL bFile, BOOL bWriteIntermFiles, BOOL bSaveIntermResults);
    void DeleteProcessors();
    BOOL LoadSyntaxModule(MorphLanguageEnum langua);
    BOOL BuildSyntax(BOOL bSaveIntermResults);
    BOOL GetSentencesFromSynAn(string str, BOOL bFile, BOOL bWriteIntermFiles, BOOL bSaveIntermResults);



    };
    extern string GetClauseTypeDescr(MorphLanguageEnum Language, const SYNANLib::IClausePtr& piClause, int ClauseRootNo);
    #endif
    }[/codebox]


    "COMSyntaxHolder.cpp"
    [codebox]#include "stdafx.h"

    #include "COMSyntaxHolder.h"


    #define COM_TRY try {
    #define COM_CATCH(msg) } catch(...) { ErrorMessage(msg); return FALSE; }

    COMSyntaxHolderNamespace::CCOMSyntaxHolder::CCOMSyntaxHolder()
    {
    };

    COMSyntaxHolderNamespace::CCOMSyntaxHolder::~CCOMSyntaxHolder()
    {
    DeleteProcessors();
    };
    BOOL COMSyntaxHolderNamespace::CCOMSyntaxHolder::GetSentencesFromSynAn(string str, BOOL bFile, BOOL bWriteIntermFiles, BOOL bSaveIntermResults)
    {
    if (!BuildBeforeSyntax(str, bFile, bWriteIntermFiles, bSaveIntermResults))
    return FALSE;

    return BuildSyntax(bSaveIntermResults);
    };

    BOOL COMSyntaxHolderNamespace::CCOMSyntaxHolder::LoadSyntaxModule(MorphLanguageEnum langua)
    {
    try
    {
    m_piSentCollection = 0;
    HRESULT hr = m_piSentCollection->CreateInstance(__uuidof(SYNANLib::SentencesCollection));
    if( FAILED(hr) )
    {
    ErrorMessage("SynAn has crushed, maybe \"SynAn.dll\" is not registered.");
    return FALSE;
    }


    m_piSentCollection->GetInterfacePtr()->PutSyntaxLanguage(langua);
    m_piSentCollection->GetInterfacePtr()->SetLemmatizer(m_piLemmatizer->GetInterfacePtr());


    if (langua != morphRussian)
    {
    m_piSentCollection->GetInterfacePtr()->PutEnableThesauri( FALSE);
    };

    m_piSentCollection->GetInterfacePtr()->PutKillHomonymsMode(CoverageKillHomonyms);


    hr = m_piSentCollection->GetInterfacePtr()->InitializeProcesser();
    if( FAILED(hr) )
    {
    ErrorMessage("Can not load syntax dictionaries.");
    return FALSE;
    }

    }
    catch(...)
    {
    ErrorMessage("SynAn has crushed, maybe \"SynAn.dll\" is not registered.");
    return FALSE;
    }
    return TRUE;
    };

    BOOL COMSyntaxHolderNamespace::CCOMSyntaxHolder::LoadSyntax(MorphLanguageEnum langua)
    {
    HRESULT hr;
    try
    {
    m_piGraphan = 0;
    m_piGraphan->CreateInstance(__uuidof(GRAPHANLib::GraphmatFile));
    m_piGraphan->GetInterfacePtr()->PutLanguage(langua);
    m_piGraphan->GetInterfacePtr()->LoadDicts();

    m_piLemmatizer = 0;
    if (langua == morphRussian)
    hr = m_piLemmatizer->CreateInstance(__uuidof(LEMMATIZERLib::LemmatizerRussian));
    else
    if (langua == morphGerman)
    hr = m_piLemmatizer->CreateInstance(__uuidof(LEMMATIZERLib::LemmatizerGerman));
    else
    if (langua == morphEnglish)
    hr = m_piLemmatizer->CreateInstance(__uuidof(LEMMATIZERLib::LemmatizerEnglish));
    if( FAILED(hr) )
    {
    ErrorMessage("CCOMSyntaxHolder", "MorphAn has crushed, maybe \"lemmatizer.dll\" is not registered.");
    return FALSE;
    }


    hr = m_piLemmatizer->GetInterfacePtr()->LoadDictionariesRegistry();
    if( FAILED(hr) )
    {
    ErrorMessage("Can not load morphology dictionaries.");
    return FALSE;
    }

    m_pGramTab = 0;
    if (langua == morphRussian)
    hr = m_pGramTab->CreateInstance(__uuidof(AGRAMTABLib::RusGramTab));
    else
    if (langua == morphGerman)
    hr = m_pGramTab->CreateInstance(__uuidof(AGRAMTABLib::GerGramTab));
    else
    if (langua == morphEnglish)
    hr = m_pGramTab->CreateInstance(__uuidof(AGRAMTABLib::EngGramTab));

    if( FAILED(hr) )
    {
    ErrorMessage("MorphAn has crushed, maybe \"agramtab.dll\" is not registered.");
    return FALSE;
    }

    hr = m_pGramTab->GetInterfacePtr()->Load();
    if( FAILED(hr) )
    {
    ErrorMessage("Can not load rusgramtab .");
    return FALSE;
    }

    }
    catch(...)
    {
    ErrorMessage("MorphAn has crushed, maybe \"lemmatizer.dll\" is not registered.");
    return FALSE;
    }

    try
    {
    m_piAfterMorphPlmLines = 0;
    m_piBeforeSyntaxPlmLines = 0;

    if( FAILED( m_piMAPost->CreateInstance(__uuidof(MAPOSTLib::MAPost)) ) )
    ErrorMessage("Mapost has crushed, maybe \"Mapost.dll\" is not registered.");

    if (langua != morphEnglish)
    m_piMAPost->GetInterfacePtr()->Init(langua, m_piLemmatizer->GetInterfacePtr() , m_pGramTab->GetInterfacePtr() );

    }
    catch(...)
    {
    ErrorMessage("Postmorphology has crushed, maybe \"MApost.dll\" is not registered.");
    return FALSE;
    }


    if (!LoadSyntaxModule(langua))
    return FALSE;

    m_CurrentLanguage = langua;

    return TRUE;
    };

    BOOL COMSyntaxHolderNamespace::CCOMSyntaxHolder::BuildBeforeSyntax(string str, BOOL bFile, BOOL bWriteIntermFiles, BOOL bSaveIntermResults)
    {
    m_piBeforeSyntaxPlmLines = 0;
    m_piAfterMorphPlmLines = 0;
    HRESULT hr = m_piAfterMorphPlmLines->CreateInstance(__uuidof(LEMMATIZERLib::PLMLineCollection));
    m_piAfterMorphPlmLines->GetInterfacePtr()->AttachLemmatizer(m_piLemmatizer->GetInterfacePtr() );

    m_piSentCollection->GetInterfacePtr()->ClearSentences();
    string log_path;
    string FileName = "rossdev.log";
    try {

    log_path = GetRegistryString( "Software\\Dialing\\Logs\\Main" );
    log_path += "/";
    }
    catch (...) {
    };
    if (bFile)
    if (!FileExists(str.c_str()))
    {
    ErrorMessage (Format("file %s is not found", str.c_str()));
    return FALSE;
    };


    COM_TRY


    if( bFile )
    m_piGraphan->GetInterfacePtr()->LoadFileToGraphan(_bstr_t(str.c_str()).copy());
    else
    m_piGraphan->GetInterfacePtr()->LoadStringToGraphan(_bstr_t(str.c_str()).copy());




    COM_CATCH( "GraphAn has crushed.");




    COM_TRY
    m_piAfterMorphPlmLines->GetInterfacePtr()->ProcessHyphenWords(m_piGraphan->GetInterfacePtr() );


    m_piAfterMorphPlmLines->GetInterfacePtr()->ProcessPlmLines(m_piGraphan->GetInterfacePtr() );
    if (bWriteIntermFiles)
    m_piAfterMorphPlmLines->GetInterfacePtr()->SaveToFile(string(log_path+"before.lem").c_str());

    if (!bSaveIntermResults)
    m_piGraphan->GetInterfacePtr()->FreeTable();


    COM_CATCH( "MorphAn has crushed.");

    COM_TRY
    if (m_CurrentLanguage == morphEnglish)
    {
    m_piBeforeSyntaxPlmLines = 0;
    m_piBeforeSyntaxPlmLines->CreateInstance(__uuidof(LEMMATIZERLib::PLMLineCollection));
    m_piBeforeSyntaxPlmLines->GetInterfacePtr()->AttachLemmatizer(m_piLemmatizer->GetInterfacePtr() );
    m_piBeforeSyntaxPlmLines->GetInterfacePtr()->CopyItems(m_piAfterMorphPlmLines->GetInterfacePtr());
    }
    else
    //m_piMAPost->GetInterfacePtr()->ProcessData(m_piAfterMorphPlmLines->GetInterfacePtr()).QueryInterface(__uuidof(LEMMATIZERLib::PLMLineCollection),
    m_piBeforeSyntaxPlmLines) ;
    if (bWriteIntermFiles)
    m_piBeforeSyntaxPlmLines->GetInterfacePtr()->SaveToFile(string(log_path+"after.lem").c_str());

    COM_CATCH( "PostMorphology has crushed.");

    if (!bSaveIntermResults)
    m_piAfterMorphPlmLines->GetInterfacePtr()->Clear();

    return TRUE;
    };

    BOOL COMSyntaxHolderNamespace::CCOMSyntaxHolder::BuildSyntax(BOOL bSaveIntermResults)
    {
    COM_TRY

    assert( !(m_piSentCollection == NULL) );
    HRESULT hr = m_piSentCollection->GetInterfacePtr()->raw_ProcessData(m_piBeforeSyntaxPlmLines->GetInterfacePtr() );
    if( FAILED(hr) )
    {
    m_piBeforeSyntaxPlmLines = 0;
    ErrorMessage("SynAn has crushed.");
    return FALSE;
    }

    if (!bSaveIntermResults)
    m_piBeforeSyntaxPlmLines->GetInterfacePtr()->Clear();



    COM_CATCH( "SynAn has crushed.")

    return TRUE;
    };



    void COMSyntaxHolderNamespace::CCOMSyntaxHolder::DeleteProcessors()
    {
    m_piLemmatizer = NULL;
    m_pGramTab = NULL;
    m_piSentCollection = NULL;
    m_piGraphan = 0;
    m_piAfterMorphPlmLines = 0;
    m_piBeforeSyntaxPlmLines = 0;
    m_piMAPost = 0;
    };


    string COMSyntaxHolderNamespace::GetClauseTypeDescr(MorphLanguageEnum Language, const SYNANLib::IClausePtr& piClause, int ClauseRootNo)
    {
    if (ClauseRootNo == -1)
    {
    if (Language == morphRussian)
    return "ПУСТЫХА";
    else
    return "EMPTY";
    }
    else
    {
    return (const char*)piClause->ClauseRoots[ClauseRootNo]->GetDescription();
    }
    };[/codebox]

    Не пойму в чём дело...какая разница между LoadSyntax и GetSentencesFromSynAn? :wacko:
     
  7. alexsid

    alexsid Гость

    Репутация:
    0
    Надо переопределить FALSE и morphRussian

    Это разные методы.

    ИМХО вообще определять класс C++ как managed было не надо. Надо было оставить его как есть.
    И просто зарегистрировать COM объект в системе и сделать на него референс из С#.
     
Загрузка...
Похожие Темы - Обращение классу C++
  1. Bafomet
    Ответов:
    20
    Просмотров:
    1.007
  2. Shouldercannon
    Ответов:
    1
    Просмотров:
    512
  3. proteam
    Ответов:
    7
    Просмотров:
    931
  4. Вовкин
    Ответов:
    0
    Просмотров:
    795
  5. Вовкин
    Ответов:
    0
    Просмотров:
    748

Поделиться этой страницей