【发布时间】:2021-09-12 09:24:31
【问题描述】:
我正在为 C 库编写 CLI/C++ 包装器,以便在 C# 中使用它。必须说,我只能访问C头文件和C库的.lib,不能访问源代码。
我试图包装的一些函数返回不透明的句柄,例如:
typedef struct SanEvent_s *SanEvent;
typedef struct SanValue_s *SanValue;
在 C# 端返回这种类型的对象对我来说似乎很麻烦,因为我不知道结构的实现(我尝试在 C++ 包装器中返回 SanEvent 类型,但在 C# 端该类型不可访问由于“保护级别”或任何它所说的)。因此,我目前的计划是编写一些辅助函数,它只返回一个整数,它表示例如 San Event 在列表或其他内容中。该列表将保存在托管 C++ 包装器中,我实际上可以在其中管理 San Event 类型。
我的问题是,我真的不知道如何使用这种类型的type。
这个:
using System::Collections::Generic::List;
namespace Wrapper {
public ref class Analytics
{
private:
static List<SanEvent^>^ events = gcnew List<SanEvent^>();
}
}
给我错误:句柄,指针,或引用是不允许的
右侧还抱怨预期的类型说明符 + 与上面相同的错误。
谁能给我一些提示,告诉我如何巧妙而有效地解决这个问题?我的 List 实现并非一成不变,我愿意接受更好的建议。
【问题讨论】:
-
您是否尝试过基于
SafeHandle创建托管友好的包装器?在 C++/CLI 端的这个包装器中,您可以只存储SanEvent*C++ 风格的指针并提供一组托管友好的函数来对包装的对象进行必要的操作。因此,托管代码将使用此包装器,并且当您需要在 C++ API 中的某处传递原始 C++ pinter 时,包装器将处理这些情况。根据 C++ 对象的语义,您可能还需要为此类包装器创建工厂类,以便为等于原始指针值返回相同的包装器实例。 -
@Serg 嗨。不,我不熟悉 SafeHandle。您能否举例说明这将如何适用于我的案例?听你的解释有点麻烦。
-
鉴于您的句柄是结构指针,最简单的方法可能是将其全部处理为 void 指针。因此,在 C# 中将 void* 列表作为不安全代码,将它们传递给 C++ 中也接受 void 指针的包装层,然后将它们转换为正确的类型并执行对 C 库的调用。
-
指针大小取决于架构。 x64 上的 64 位!我会调查 IntPtr 是否有任何不透明的地方。
标签: c# c++ list wrapper handle