• IDL


    ==================================================================
    MFC的DLL/EXE中无法使用属性化COM/ATL,原因在于属性化要求有module属性,否则编译不过,而如果有module属性的话,这个属性在编译时会自动生成DllMain/WinMain,与MFC中已有的会冲突。好的解决方案目前没有想到,只想到可能的一个,就是打开工程的Fx属性(C/C++ >> Output Files >> Expand Attributed Source),再修性module属性生成的代码。

    ==================================================================
    带有[out]属性的形参,如果是接口则必须是双指针类型,如果是基本类型,则可以是单指针类型;
    BSTR整体可以看作基本类型,所以BSTR*可以带上[out]。
    纯粹的[in]属性意味着,服务端只使用实参内容;如果形参是Interface指针,则可以利用接口方法间接调用client;如果是一般指针,则server只能使用指针内容而无法向client输出信息.
    纯粹的[out]属性意味着,服务端不使用实参内容而只向实参输出信息, 且形参一定是指针(基本类型)或者双指针(接口类型);
    纯粹的[int,out]属性意味着, 服务端使用实参内容的同时还向实参输出信息, 且形参一定是指针(基本类型)或者双指针(接口类型);
    ==================================================================
    接口中不能使用bool, 不能使用非基本类型如CAtlString、CComBSTR,(但是可以由基本类型组成的纯结构体?),必须返回HRESULT;
    如果要用到LPVOID形参,则方法要加上[local]属性:[local] HRESULT Method(LPVOID pVoid);
    ============================================
    来自MSDN:
    1, _ATL_ATTRIBUTES 工程中,使用IDL文件的方法是使用属性[importidl(idl_file)];
    2, 非_ATL_ATTRIBUTES工程中使用[属性]的方法是使用向导。
    ============================================
    link设置项 /ignoreidl=false时,如果调用了其它“静态库”导出的C_Style API,且该API中有使用interface为参数的话,则在生成的idl文件中会产生redefnition冲突:一是来是interface.h的定义;二是来自编译那个“静态库”时,interface.h产生的定义。两个interface.h其实是同一个文件,但是存放在在不同电脑中不同路径里的。原因是由于静态库包含了所有代码信息,属性化DLL中只要调用了静态库中任何一个函数,MIDL便会处理整个静态库工程中所有出现过的接口属性。使用动态库则没有问题,所以静态库中最好不要包含属性化接口(最好不开启静态库工程的_ATL_ATTRIBUTES属性),否则其无法在属性化并且/ignoreidl=false的ATL工程中使用。

    问题模拟重现:
    一、建立一个_ATL_ATTRIBUTES工程,并用向导添加一个atl 类,去掉生成的头文件中的类,只保留接口备用;
    二、建立一个static lib工程,并在c/c++预处理宏中加上_ATL_ATTRIBUTES, 在stdafx.h中加上atlbase.h和atlcom.h;然后再添加函数,函数形参使用第一步的接口指针;
    三、建立一个ATL DLL的属性化工程,并调用第二步的函数, 这一步在link时, MIDL便会报错 redefinition, 查看工程目录下以下划线开头的idl文件,可知问题所在。
    注:函数体可以不写,只留花括号模拟问题即可。

    猜想解决方案:
    1,[no_injected_text(true)]。先打开C/C++开关 /Fx,再修改生成的源码,并把修改后的整体paste到工程中对应的file中,然后重新编译,这次因为有no_injected_text属性,不会再生成属性代码。(不行,南辕北辙了)
    方案2, 在上面第三步中,将相关头文件位置放在与第二步相同位置(已经证实可行)。
    方案3,在相关cpp文件中,插入idl属性[emitidl(false/restrict)];这样可以阻止该cpp文件中的idl属性产生idl代码到最后生成的idl文件中,但是阻止不了引入的静态库产生idl代码。(证实可行,相反属性[importidl(idl_file)];强制引入idl)
    ============================================
    选择了/ignoreidl=false后,要rebuild整个工程,否则会register失败,因为typelib资源没有嵌入到resource中。

    View Code
    BOOL AllowMeesageForVista(UINT uMessageID, BOOL bAllow)//注册Vista全局消息
    {
        typedef BOOL (WINAPI *_ChangeWindowMessageFilter)( UINT , DWORD);

        BOOL bResult = FALSE;
        _ChangeWindowMessageFilter pChangeWindowMessageFilter = 
            (_ChangeWindowMessageFilter) GetProcAddress( GetModuleHandle(L"user32.dll"), "ChangeWindowMessageFilter" );
        if (!pChangeWindowMessageFilter)
        {
            return FALSE;
        }

        return pChangeWindowMessageFilter( uMessageID, bAllow ? 1 : 2 );//MSGFLT_ADD: 1, MSGFLT_REMOVE: 2
    }



     

  • 相关阅读:
    CS academy Binary Flips(dp)
    [POJ 1637] Sightseeing tour(网络流)
    Codeforces 346D Robot Control(01BFS)
    BZOJ 2069: [POI2004]ZAW(Dijkstra + 二进制拆分)
    驱动之SPI,UART,I2C的介绍与应用20170118
    USB驱动之CDC类的介绍与应用20160905
    uCOS-II之移植20160823
    java之面向对象20160818
    Java之基础20160806
    Android之框架20160721
  • 原文地址:https://www.cnblogs.com/gakusei/p/2556088.html
Copyright © 2020-2023  润新知