C ++ / CLI: невозможно увидеть ссылочные сборки без использования #include - PullRequest
2 голосов
/ 05 апреля 2011

У нас есть два проекта C ++ / CLI, проект с чистым CLR и проект со смешанным режимом, который предоставляет нашему неуправляемому доступу на базе кода к проекту с чистым CLR.У нас возникают проблемы с тем, чтобы проект смешанного режима мог видеть символы, определенные в чистом проекте CLR.

В частности, у нас есть форма, называемая MainForm, определенная в чисто управляемом проекте.Это типичная форма C ++ / CLI Windows:

MainForm.h:

public ref class MainForm : public System::Windows::Forms::Form
{
public:
    MainForm(void)
    {
        InitializeComponent();
        //
        //TODO: Add the constructor code here

    }
    ...
};

Наш проект «обертки» в смешанном режиме пытается использовать его, например:

ManagedDialogProvider.h:

namespace ManagedWrapper
{
    public ref class ManagedDialogProvider
    {
        static void ShowDialog()
        {
             OurManagedComponents::MainForm^ form = gcnew OurManagedComponents::MainForm();
        }
    };
}

(У нас есть класс C ++ / MFC в проекте смешанного режима, CManagedDialogProvider, который вызывает ManagedDialogProvider, чтобы наш неуправляемый код мог его использовать. Ошибка там не возникает, однако.)

Когда я пытаюсь создать проект в смешанном режиме, он говорит мне, что MainForm не является членом OurManagedComponents.(Ошибка в ManagedWrapper :: ManagedDialogProvider :: ShowDialog ().)

Примечания:

  • Проект в смешанном режиме имеет ссылку на управляемый проект.
  • Я попытался использовать #include в верхней части класса управляемой оболочки вместо ссылки, и, хотя это скомпилировано, я не смог загрузить форму из-за того, что ее ресурсы не были найдены.Я отказался от этого решения, так как оно не принято, если я правильно понимаю;Проекты .NET должны ссылаться друг на друга только через ссылки на сборки.
  • Я проверил, что управляемый класс доступен (общедоступный).
  • Я проверил обозреватель объектов, чтобы убедиться, что OurManagedComponentsвидимый и содержит MainForm.

Есть идеи?Тот же проект в смешанном режиме без проблем переносит управляемые компоненты C #, но когда я попытался использовать тот же подход для этого управляемого компонента C ++ / CLI, появились эти проблемы.

Ответы [ 3 ]

2 голосов
/ 12 апреля 2011

Оказалось, что OurManagedComponents :: MainForm не имеет файла реализации (.cpp);у него был только файл .h.Естественно, что MainForm никогда не создавался и не был связан с проектом.(Интересно, что в браузере объектов все еще отображался OurManagedComponents :: MainForm, и проект по-прежнему создавался просто отлично; он должен видеть объявленные типы независимо от того, реализованы ли они).Что я могу сказать, я слишком долго использовал C #: -)

Как только я создал MainForm.cpp (пустой, но для , включающий "MainForm.h" ) и перестроил, всеработал.

0 голосов
/ 05 апреля 2011

Тогда у нас есть неуправляемый класс в тот самый проект, который называет ManagedDialogProvider так что наши неуправляемый код может использовать его.

Неуправляемый (собственный) код не может получить доступ к управляемому коду без надлежащих обратных вызовов.
Подумайте о коде ниже.

// CMainDialogProvider.h

typedef void (*ShowDialogNativeCB)() ;

class CMainDialogProvider
{
//..
public:
  ShowDialogNativeCB nativeCB;
//..

}

// ManagedDialogProvider.h
#include "CMainDialogProvider.h"

public delegate void ShowDialogClrCB ();

namespace ManagedWrapper
{
   // ....
   //somehow you have to provide the ShowDialog() function as a callback;
   ShowDialogClrCB ^ clrCB = gcnew ShowDialogClrCB(&ManagedDialogProvider::ShowDialog());
   GCHandle clrCBhandle = GCHandle::Alloc(clrCB);
   // to prevent the garbage collection of delegate.
   // but this must be freed later. 
   IntPtr ip = Marshal::GetFunctionPointerForDelegate(clrCB);
   // Lets say Instance is an instance of CMainDialogProvider.
   Instance->nativeCB = static_cast<ShowDialogNativeCB>(ip.ToPointer());
   //...
}

#include "stdafx.h"
#include "CManagedDialogProvider.h" // C++ class
#include "ManagedDialogProvider.h"  // .NET ref class

IMPLEMENT_DYNAMIC(CManagedDialogProvider, CObject)

void CManagedDialogProvider::ShowDialog()
{
   if(nativeCB != NULL)
     nativeCB();
}
0 голосов
/ 05 апреля 2011

Попробуйте:

ManagedWrapper::ManagedDialogProvider::ShowDialog();
...