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

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

  1. IgMuSh

    IgMuSh Гость

    Могу ли я в одном 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 Гость

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

    IgMuSh Гость

    Вот это у меня в 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 Гость

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

    Pasha Гость

    IgMuSh
    Объяви класс как public ref class CCOMSyntaxHolder.
     
  6. IgMuSh

    IgMuSh Гость

    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 Гость

    Надо переопределить FALSE и morphRussian

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

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

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