none
如何使用DllImport调用这个c++函数? RRS feed

  • 问题

  • 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运行时组件项目),

    我该怎么办呢?









    2014年1月20日 16:18

答案

  • 很抱歉这么晚才给您回复,项目已共享到skydrive:

    https://skydrive.live.com/redir?resid=5AF370ECCEBE027D%213627

    • 已标记为答案 jesse hao 2014年3月26日 10:27
    2014年2月14日 5:19

全部回复

  • 给你的 string 变量标记上:

    (UnmanagedType.LPTStr)]

    2014年1月21日 2:21
  • [MarshalAs(UnmanagedType.LPTStr)]
            public string lpTitle;

    我这样写又报错了:

    The attribute 'System.Runtime.InteropServices.MarshalAsAttribute' is not supported. Error on 'SystemApiLib.TOAST_MESSAGE.lpTitle'.

    2014年1月21日 3:55
  • [MarshalAs(UnmanagedType.LPTStr)]
            public string lpTitle;

    我这样写又报错了:

    The attribute 'System.Runtime.InteropServices.MarshalAsAttribute' is not supported. Error on 'SystemApiLib.TOAST_MESSAGE.lpTitle'.

    请说明是编译时错误,还是运行时错误?


    2014年1月22日 1:14
  • 你好,

    据我所知,Windows Phone 8现在还不支持DllImport。参考:https://connect.microsoft.com/VisualStudio/feedback/details/777333/add-dllimport-support-for-net-in-windows-phone-8

    可以考虑直接用WindowsPhoneRuntimeComponent实例调用,举个例子:

    使用Windows phone App模板创建一个WP8 应用程序,接着为解决方案添加一个Visual C++项目,选择Windows Phone Runtime Component模板,命名为WpRuntimeComponent。为Windows Phone项目添加刚刚创建的WpRuntimeComponent的引用。接着在C++项目中写好需要调用的方法。然后在WP8项目的MainPage.xaml.cs中创建一个WindowsPhoneRuntimeComponent 实例:

    private WindowsPhoneRuntimeComponent com = new WindowsPhoneRuntimeComponent();

    接着,调用C++方法:

    com.Add(Convert.ToInt32(txt1.Text), Convert.ToInt32(txt2.Text)).ToString();
    希望有所帮助。

    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年1月23日 7:44
    版主
  • 你好,

    这是编译时错误,我的项目类型是“windows 应用商店 -> windows 运行时组件”项目,

    2014年1月24日 3:14
  • 你好,

    本论坛讨论Windows Phone相关问题,Windows 应用商店的问题,请在这个论坛提问以获取更好的帮助:http://social.msdn.microsoft.com/Forums/zh-CN/home?forum=winstoreappzhcn

    谢谢谅解。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年1月24日 3:21
    版主
  • 多谢,

    我使用的就是“windows运行时组件”项目,与您所说的略有不同:

    我先建立了一个WP8的项目,然后建立了一个c#版的“windows运行时组件(WindowsPhoneRuntimeComponent)”项目,然后在运行时组件项目中使用 DllImport 调用native api,

    奇怪的是,我调用其他方法都是对的,比如 Shell_TurnScreenOn 方法,就可以正常运行,

    可就是调用 Shell_PostMessageToast 的时候有问题:

    Shell_PostMessageToast 这个方法是弹出一个 toast通知,我调用后,可以弹出这个toast,但 toast 中是空的(我确信已经传值),我想是不是我传值的方式不对,比如应该传指针,而我传的不是指针等等....

    2014年1月24日 3:23
  • 你好,

    你能提供一个能重现该问题的、简化的代码么?可以上传到skydrive并贴出链接。

    Thanks.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年1月27日 6:53
    版主
  • 不让用的话,把它们都转换成 IntPtr。

    public IntPtr lpTitle;
    public IntPtr lpContent;
    public IntPtr lpUri;
    public IntPtr lpType;

    然后再用 Marshal 的方法把 IntPtr 转换成 string。


    2014年2月7日 2:23
  • 很抱歉这么晚才给您回复,项目已共享到skydrive:

    https://skydrive.live.com/redir?resid=5AF370ECCEBE027D%213627

    • 已标记为答案 jesse hao 2014年3月26日 10:27
    2014年2月14日 5:19
  • 你上传的工程里的component加载不成功。
    2014年2月14日 5:39
  • 我在本机调试通过,

    windows phone项目不能直接引用那个运行时组件,

    只能通过引用外部文件,然后浏览到winmd文件,再引用,

    2014年2月15日 4:38