【问题标题】:Generic List in C# DLL cannot be accessed from CLI无法从 CLI 访问 C# DLL 中的通用列表
【发布时间】:2015-04-01 19:56:54
【问题描述】:

首先要指出我是 C++/CLI 的新手

我们有一个解决方案,其中包含一个非托管 C++ 应用程序项目(我们将称为“应用程序”)和一个构建为 DLL 的 C# .net 远程处理项目(我们将称为“远程处理”),以及一个用于接口的 CLI 项目两者之间(我们称之为“桥”)。

似乎一切正常,我们在 Bridge 中有一个 IMyEventHandler 接口,它成功接收来自 Remoting 的事件并可以调用 Application 中的方法。

#ifndef EVENTS_HANDLER_INTERFACE_H_INCLUDED
#include "EventsHandlerInterface.h"
#endif

#define DLLEXPORT __declspec(dllexport)
#ifdef __cplusplus
extern "C"
{
#endif
    DLLEXPORT bool RegisterAppWithBridge(IMyEventsHandler * aHandler);
    DLLEXPORT void PostEventToServer(AppToServerEvent eventType);
    DLLEXPORT void PollEventsFromServer();
#ifdef __cplusplus
}
#endif

在 Bridge 实现中,我们有一个处理事件的方法,根据事件类型,我们将调用不同的方法来处理该确切类型:

void Bridge::OnReceiveServerEvent(IMyEvent^ aEvent)
{
    // Determine event type
    ...
    Handle_SpecificEventType();
}

到目前为止,这一切都运行良好。一旦我们为已知类型的事件调用处理程序,我们就可以直接从通用接口类型转换为它。这就是我们开始看到问题的地方。所有这些事件类型都在从 C# 生成的另一个 DLL 中定义。只有整数或字符串的简单事件可以正常工作,但我们有这个 SpecificEventType,其中包含其他类型的列表(我们将调用“AnotherType”),所有这些都在另一个 DLL 中定义。所有必需的 DLL 都已作为引用添加,我可以 gcnew 一个 AnotherType 而不会抱怨。

但是,一旦我尝试从列表中取出 AnotherType 元素,我们就会看到构建错误:“C2526 'System::Collections::Generic::List::GetEnumerator' C 链接函数无法返回 C++ 类”

void Bridge::Handle_SpecificEventType(IMyEvent ^evt)
{
    SpecificEventType ^e = (SpecificEventType ^)evt;

    // We can pull the list itself, but accessing elements gives error
    System::Collections::Generic:List<AnotherType ^> ^lst = e->ThatList;

    // These all cause error
    array<AnotherType ^> ^arr = lst->ToArray();

    AnotherType ^singleElement = lst[0];

    for each(AnotherType ^loopElement in lst){}
}

为了阐明我们这样做的原因,我们尝试获取在 C# DLL 中定义并通过 .net 远程处理从较新的 C# 服务器发送的托管事件,并为较旧的非托管 C++ 应用程序“翻译”它们。所以最终目标是创建 C# 类型“SpecificEventType”的副本并将其转换为非托管“SpecificEventType_Unmanaged”,然后使用该数据调用应用程序:

// Declared in Bridge.h and gets assigned from DLLEXPORT RegisterGameWithBridge method.
IMyEventsHandler *iApplicationEventHandler;

// Bridge.cpp
void Bridge::Handle_SpecificEventType(IMyEvent ^evt)
{
    ... Convert SpecificEventType to SpecificEventType_Unmanaged
    iApplicationEventHandler->Handle_SpecificEvent(eventUnmanaged);
}

这个消息似乎工作和设置正确 - 但它真的不想给我们通用列表中的元素 - 阻止我们提取数据并构建事件的非托管版本以发送到应用。

我希望我已经很好地解释了这一点,我还是 CLI 的新手,并且已经有几年没有接触过 C++ 了 - 如果需要任何其他详细信息,请告诉我。

提前感谢您的帮助。

【问题讨论】:

    标签: dll c++-cli clr unmanaged .net-remoting


    【解决方案1】:

    原来问题是因为 Bridge 实现中的所有方法仍在外部“C”块内。浪费了这么多时间 - 这么简单的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多