c++声明如下:
typedef struct _TOAST_MESSAGE { CLSID guid; LPCWSTR lpTitle; LPCWSTR lpContent; LPCWSTR lpUri; LPCWSTR lpType;
} TOAST_MESSAGE;
extern"C" WINADVAPI VOID APIENTRY Shell_PostMessageToast(_In_ TOAST_MESSAGE* toastMessage );
我想在C#中使用P/Invoke调用它,于是这样写的:
public struct _TOAST_MESSAGE {
public Guid guid;
public string lpTitle;
public string lpContent;
public string lpUri;
public string lpType;
}
[DllImport("ShellChromeApi.dll")]
private static extern void Shell_PostMessageToast(ref _TOAST_MESSAGE data);
发现这个代码并没有正常工作:正常情况下界面上应该有lpTitle,lpContent这两行文字的,但我这样调用,界面上这两行文字是空的,也没有提示错误,我不知道c++中的 LPCWSTR在c#中对应什么类型,但在c#中改为char*指针类型,又会提示项目部能使用指针(这是windows运行时组件项目),
我该怎么办呢?
pinvoke的数据结构封装是一件非常麻烦的事情,把TOAST_MESSAGE结构改成如下形式试试:
[StructLayout(LayoutKind.Sequential)] public struct TOAST_MESSAGE { public Guid guid; [MarshalAs(UnmanagedType.LPWStr)] public string lpTitle; [MarshalAs(UnmanagedType.LPWStr)] public string lpContent; [MarshalAs(UnmanagedType.LPWStr)] public string lpUri; [MarshalAs(UnmanagedType.LPWStr)] public string lpType; }
另外,建议用C++封装一下这个函数,对外公布基础类型的数据作为参数,这样更容易成功。
可以使用工具自动生成C/C++等非托管代码的C#申明。自己去下载工具CLRInsideOut。如果找不到我可以发你。
字符串哪里应该没太大问题。估计主要问题在第一个成员那个 guid 上。在c++里应该是个结构体。到c#里你那个guid是不是是个引用对象了?,如果是这样估计数据结构会错位。你最好在c#里也用一个struct来表示这个成员。