【发布时间】:2019-01-28 10:54:18
【问题描述】:
我正在用 win32 c++ 编写“ICS/VCS”文件解析器。
从文件反序列化后,我将事件数据存储在事件结构列表中。
现在我想在 c# 中访问该结构化列表。 为此,我在 DLL 中导出了函数和列表。
我不知道如何在 c# 中访问该列表。
这是我的事件结构:
struct Event {
Event(): Alarms(new list<Alarm>), RecurrenceNo(0), BaseEvent(this) {}
Event(const Event &Base) :
UID(Base.UID),
Organizer(Base.Organizer),
Summary(Base.Summary),
Description(Base.Description),
Attendee(),
Categories(Base.Categories),
DtStamp(Base.DtStamp),
DtStart(Base.DtStart),
DtEnd(Base.DtEnd),
RRule(Base.RRule),
Alarms(Base.Alarms),
AttendeeCounter(Base.AttendeeCounter),
RecurrenceNo(Base.RecurrenceNo)
{
BaseEvent = Base.BaseEvent == (Event *)&Base ? (Event *)&Base : Base.BaseEvent;
}
~Event() {
if (BaseEvent == this)
delete Alarms;
}
operator string() const;
bool HasAlarm(const Date &From, const Date &To);
string UID, Summary, Description, Categories, Attendee[100], Organizer;
int AttendeeCounter=0;
Date DtStamp, DtStart, DtEnd;
Recurrence RRule;
list<Alarm> *Alarms;
unsigned short RecurrenceNo;
Event *BaseEvent;
};
这里是 ExportFunction.h
extern list <Event *> ListofAllEvents;
extern "C" __declspec(dllexport) list <Event *> ParseCalendar(std::string FilePath);
这是我要导出的函数 "ExportFunction.cpp"
list <Event *> ParseCalendar(std::string FilePath)
{
const char * InputPath = FilePath.c_str();
ICalendar Calendar(InputPath);
return ListofAllEvents;
}
这是 Program.cs
[DllImport("D:\\Projects\\iCalander\\x64\\Debug\\iCalander.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr ParseCalendar(string FilePath);
它显示访问冲突错误。这是预期的,因为我没有正确访问。
我是 pInvoke 和编组的新手。
【问题讨论】:
-
google for ""std::string" C# interop" ...正确的答案是你不应该这样做(将 std::string 暴露给 C#)...传递普通的
(w)char*...编辑:您也不应该公开任何标准 C++ 对象(如 std::list) -
我也是这么想的。但我需要在我的 c# 应用程序中访问已解析的内容。你有更好的解决方案吗?
-
对于字符串参数,必须使用
char*或wchar_t*(或BSTR)。对于该对象,确定您可以返回一个指向 C# 的不透明指针,但是您将如何处理它呢?您可以将其想象为 C# 将 C++ 代码视为 C(指针、基类型、结构等,没有类)。考虑二进制布局。 -
我只使用字符串从 c# 获取文件路径。我在 C++ 应用程序内部使用 char*。这是因为 CLR 我不得不使用字符串。
-
@SimonMourier 你能指出我如何访问该列表的地方吗?我想在 c# 应用程序中执行 db 操作。
标签: c# c++ com interop marshalling