我们有两个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();
}
};
}
(然后我们在混合模式项目CManagedDialogProvider中有一个C ++ / MFC类,它调用ManagedDialogProvider以便我们的非托管代码可以使用它。但是,那里没有发生错误。)
当我尝试构建混合模式项目时,它告诉我MainForm不是OurManagedComponents的成员。 (ManagedWrapper :: ManagedDialogProvider :: ShowDialog()中的错误。)
注意:
有什么想法吗?相同的混合模式项目在包装C#托管组件时没有问题,但是当我尝试对此C ++ / CLI托管组件使用相同的方法时,会出现这些问题。
答案 0 :(得分:2)
事实证明,OurManagedComponents :: MainForm没有实现文件(.cpp);它只有一个.h文件。很自然,MainForm从未实际构建或链接到项目中。 (有趣的是,对象浏览器仍然显示OurManagedComponents :: MainForm并且项目仍然构建得很好;它必须看到声明的类型,无论它们是否已实现)。我能说什么,我一直在使用C#太长了: - )
一旦我创建了一个MainForm.cpp(空的但是包含“MainForm.h”)并重建,一切都运转了。
答案 1 :(得分:0)
尝试:
ManagedWrapper::ManagedDialogProvider::ShowDialog();
答案 2 :(得分:0)
然后我们有一个非托管类 调用的那个项目 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();
}