zoukankan      html  css  js  c++  java
  • Win8多平台引用配置

    之前移植过DLNA的库,这个库是C++写的,然后我们的项目是C#的。接着很郁闷的事情发生了,主项目引用一个C#的DLL,然后这个DLL引用这个C++/CX封装的库。如果有C++的源代码的话,做项目依赖就很简单。如果是引用DLL的话,切换平台,这些DLL就要被覆盖一遍,而且经常会出现DLL加载失败的错误。
     
    我最初的做法就是把这些DLL 都添加到主项目里面,在属性页中设置复制到输出目录。这种做法有个问题,就是这个DLL无法被添加到引用中。
     
    后来,受到C++项目条件编译的启发,改写了一下C#的项目配置文件,在里面添加Choose节点。有个这个节点,就可以根据不同的平台,引用不同的DLL
     
     <Choose>
        <When Condition ="'$(Platform)' == 'ARM'">
          <ItemGroup>
            <Reference Include="PLTWinRt">
              <HintPath>>..Win8ReferenceDllARMPLTWinRt.winmd</HintPath>
            </Reference>
          </ItemGroup>
        </When>
        <Otherwise>
          <ItemGroup>
            <Reference Include="PLTWinRt">
              <HintPath>..Win8ReferenceDllX86PLTWinRt.winmd</HintPath>
            </Reference>
          </ItemGroup>
        </Otherwise>
      </Choose>
     
    对于主项目中添加的DLL,我采用预先生成事件命令行,把对应的DLL覆盖一下。
     
      <PropertyGroup Condition=" '$(Platform)' == 'x86'">
        <PreBuildEvent>Copy "$(ProjectDir)ReferenceDllX86*.*" "$(ProjectDir)"</PreBuildEvent>
      </PropertyGroup>
      <PropertyGroup Condition=" '$(Platform)' == 'ARM'">
        <PreBuildEvent>Copy "$(ProjectDir)ReferenceDllARM*.*" "$(ProjectDir)"</PreBuildEvent>
      </PropertyGroup>
    这样做法的好处就是可以让所有的DLL和EXE在同一个目录下面,如果采用前面的方式,那这些DLL会在子文件夹中。就可能出现加载不正常的问题。
     
    如何诊断DLL加载是否正常,在Win8这里没有太好的工具去看,depends.exe看不了C#项目的引用,lldasm.exe会看到引用,但是不能确定是否正确加载,Fuslogvw.exe似乎看不到win8项目的DLL引用过程。
     
    一个C++/CX的WinRt组件会有两个文件,一个PpboxRT.winmd和PpboxRT.dll。引用的时候,VS会输出加载winmd文件,如果对应.dll文件引用其他dll文件,其他的dll文件找不到了就会抛出FileNotFoundException 错误。
     
    这个时候,我们要去项目的目录中去找对应的DLL有没有复制到指定目录里 Win8inx86DebugAppX
     
    另外,在这个目录里面还有AppxManifest.xml 文件,这个文件中记录着winmd文件和dll文件中的类的关联信息
        <Extension Category="windows.activatableClass.inProcessServer">
          <InProcessServer>
            <Path>PLTWinRt.dll</Path>
            <ActivatableClass ActivatableClassId="PLTWinRt.DMR_PositionInfo" ThreadingModel="both" />
            <ActivatableClass ActivatableClassId="PLTWinRt.DMR_ConnectionInfo" ThreadingModel="both" />
            <ActivatableClass ActivatableClassId="PLTWinRt.DMR_MediaInfo" ThreadingModel="both" />
            <ActivatableClass ActivatableClassId="PLTWinRt.MediaController" ThreadingModel="both" />
            <ActivatableClass ActivatableClassId="PLTWinRt.DMR_TransportSettings" ThreadingModel="both" />
            <ActivatableClass ActivatableClassId="PLTWinRt.DMR_TransportInfo" ThreadingModel="both" />
          </InProcessServer>
        </Extension>
    当然这个节点也可以强行添加到Package.appxmaniest文件中。
  • 相关阅读:
    Mac 虚拟机VMware Fusion显示内部错误的解决方法
    Linux系统中的引导过程与服务控制
    linux系统中如何删除lvm分区
    Linux命令下: LVM逻辑卷配置过程详解(创建,增加,减少,删除,卸载)
    解决:rm: 无法删除"tomcat": 设备或资源忙
    LVM操作过程
    Linux命令下进行硬盘挂载、分区、删除分区,格式化,卸载方法
    finger 命令查询用户名、主目录、停滞时间、登录时间
    【MySQL】MySQL5.7传统复制切换为GTID复制
    深入理解MySQL系列之锁
  • 原文地址:https://www.cnblogs.com/zjjcy/p/3419243.html
Copyright © 2011-2022 走看看